Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-2241

Resteasy cannot handle MultivaluedMap in restful service

    XMLWordPrintable

Details

    • Bug
    • Resolution: Won't Do
    • Major
    • None
    • 3.6.3.Final, 4.0.0.Final
    • jaxrs
    • None
    • Hide

      1. Create a web project based on spring MVC
      2. Create a component named ExampleRestApi, example code is like below

      @Component(value = "ExampleRestApi")
      @Path("/rest")
      @Produces(value = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      public class ExampleRestApi {
          @Override
          @POST
          @Path("validateParam/")
          @Produces({ "application/json", "application/xml" })
          public String validateParam(MultivaluedMap<String, String> parameters){
             return parameters.get("param1");
          }
      }
      

      3. Build the war from the web project and deploy in wildfly
      4. Use soapui client to create a post request to the restful service
      1) url : http://localhost:8080/rest/validateParam
      2) Media Type : application/x-www-form-urlencoded
      3) Body : param1=terry&param1=abc
      5) Expected result should be "terry", but got empty string or null actually.

      Show
      1. Create a web project based on spring MVC 2. Create a component named ExampleRestApi, example code is like below @Component(value = "ExampleRestApi" ) @Path( "/ rest " ) @Produces(value = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public class ExampleRestApi { @Override @POST @Path( "validateParam/" ) @Produces({ "application/json" , "application/xml" }) public String validateParam(MultivaluedMap< String , String > parameters){ return parameters.get( "param1" ); } } 3. Build the war from the web project and deploy in wildfly 4. Use soapui client to create a post request to the restful service 1) url : http://localhost:8080/rest/validateParam 2) Media Type : application/x-www-form-urlencoded 3) Body : param1=terry&param1=abc 5) Expected result should be "terry", but got empty string or null actually.
    • Hide

      Workaround is to create a ContainerRequestFilter to inject the parameter

      import org.jboss.resteasy.core.interception.PreMatchContainerRequestContext;
      import org.jboss.resteasy.plugins.server.servlet.HttpServletInputMessage;
      
      import javax.ws.rs.container.ContainerRequestContext;
      import javax.ws.rs.container.ContainerRequestFilter;
      import javax.ws.rs.container.PreMatching;
      import javax.ws.rs.ext.Provider;
      import java.io.IOException;
      
      @PreMatching
      @Provider
      public class InjectParameterFilter implements ContainerRequestFilter {
          @Override
          public void filter(ContainerRequestContext containerRequestContext) throws IOException {
              if (containerRequestContext instanceof PreMatchContainerRequestContext) {
                  PreMatchContainerRequestContext preMatchContainerRequestContext = (PreMatchContainerRequestContext) containerRequestContext;
                  if (preMatchContainerRequestContext.getHttpRequest() instanceof HttpServletInputMessage) {
                      ((HttpServletInputMessage) preMatchContainerRequestContext.getHttpRequest()).getDecodedFormParameters();
                  }
              }
          }
      }
      
      Show
      Workaround is to create a ContainerRequestFilter to inject the parameter import org.jboss.resteasy.core.interception.PreMatchContainerRequestContext; import org.jboss.resteasy.plugins.server.servlet.HttpServletInputMessage; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.PreMatching; import javax.ws.rs.ext.Provider; import java.io.IOException; @PreMatching @Provider public class InjectParameterFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext containerRequestContext) throws IOException { if (containerRequestContext instanceof PreMatchContainerRequestContext) { PreMatchContainerRequestContext preMatchContainerRequestContext = (PreMatchContainerRequestContext) containerRequestContext; if (preMatchContainerRequestContext.getHttpRequest() instanceof HttpServletInputMessage) { ((HttpServletInputMessage) preMatchContainerRequestContext.getHttpRequest()).getDecodedFormParameters(); } } } }

    Description

      1. From resteasy-core/org.jboss.resteasy.core.MessageBodyParameterInjector.inject(HttpRequest, HttpResponse, boolean)
      it call HttpServletInputMessage.formParametersRead before calling resteasy-core/org.jboss.resteasy.plugins.server.servlet.HttpServletInputMessage.getDecodedFormParameters, but the first value assigment of variable decodedFormParameters is in method HttpServletInputMessage.getDecodedFormParameters.
      2. The resteasy would not parse the MultivaluedMap parameter because the parameter check without parameter initialization

      Attachments

        Activity

          People

            Unassigned Unassigned
            terryyrliang terry liang (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: