Results 1 to 7 of 7

Thread: REST POST with MultiValueMap is always empty

  1. #1
    Join Date
    Jul 2009
    Posts
    2

    Question REST POST with MultiValueMap is always empty

    I've just started working with Spring 3.0 M3 to write a REST API for use instead of an existing SOAP API. I followed the instructions for creating a restful service. Any methods that I've annotated as POST that take a @RequestBody MultiValueMap never receive a populated Map. If I create an equivalent method with a PUT the map is successfully populated. Here's two examples:

    @RequestMapping(value = "/service/postTest", method = RequestMethod.POST)
    public String testPost(@RequestBody MultiValueMap<String, Object> params,
    Model model)
    {
    System.out.println(params);
    return "redirect:/service/token/" + 1;
    }

    @RequestMapping(value = "/service/putTest", method = RequestMethod.PUT)
    public void testPut(@RequestBody MultiValueMap<String, Object> params,
    Model model)
    {
    System.out.println(params);
    }

    As you can see the two methods are identical except for the URI, request method, and the PUT doesn't return a value. I'm using the RestTemplate in a simple main method to call the methods. I tried running the WAR file I created in glassfish, tomcat 6, and jetty 6. Both glassfish and tomcat exhibited the same behavior. Jetty however also exhibited the problem with the PUT method. I tried changing the MultiValueMap above to a String and this worked for POSTing in both Jetty and glassfish. I tried debugging the spring code to find the problem and I found that in the FormHttpMessageConverter method readInternal line 66 is where the problem shows up. In cases where no parameters are returned the input reader doesn't return any data in the copyToString method.

    Is there anything that I'm doing wrong? I can provide more information if needed.

  2. #2
    Join Date
    Aug 2009
    Posts
    2

    Default

    I'm having this exact same problem, though I'm POSTing through a very basic form within an HTML file.

    Code:
    @Controller
    @RequestMapping("/events/**")
    public class TrackingController {
    
    	
    	@RequestMapping(value = "/events", method=RequestMethod.POST)
    	public void logEvent(@RequestBody MultiValueMap<String,Object> params) {
    		for (String key : params.keySet()) {
    			System.out.println("key: " + key);
    			System.out.println("value: " + params.get(key));
    		}
    Here is the form:

    Code:
    <html>
        <head>
            <title>Log Event</title>
        </head>
        <body>
            <h1>Log Event</h1>
    		<form  action="http://localhost:8080/tracking/events" method="post">
    		    <table>
    		        <tr>
    		            <td>First Name:</td>
    		            <td><input type="text" name="firstName" /></td>
    		        </tr>
    		        <tr>
    		            <td>Last Name:</td>
    		            <td><input type="text" name="lastName" /></td>
    		        </tr>
    		        <tr>
    		            <td colspan="3">
    		                <input type="submit" value="Log Event" />
    		            </td>
    		        </tr>
    		    </table>
    		</form>
        </body>
    </html>

  3. #3
    Join Date
    Jul 2009
    Posts
    2

    Default

    We never found a solution to this problem. We've been using @RequestBody with JAXB generated types or @RequestParam. This works for us but it seems like a large missing feature not to allow URL encoded parameters in the message body of a POST or PUT. I'm not sure how BigErn001 will be able to work around this problem since he's using an HTML form. You may have to switch to a GET and use @RequestParam.

  4. #4
    Join Date
    Aug 2009
    Posts
    2

    Default

    I found a solution, at least for my problem. In debugging the FormHTTPMessageConverter, I notced the request body was always null. I guessed that the HiddenHTTPMethodFilter might be screwing around with the request contents so I removed it from web.xml and after that my MultiValueMap started getting populated.

    Here's what I removed:
    Code:
    	<filter>
    		<filter-name>httpMethodFilter</filter-name>
    		<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter
    		</filter-class>
    	</filter>
    	 
    	<filter-mapping>
    		<filter-name>httpMethodFilter</filter-name>
    		<servlet-name>MainDispatcher</servlet-name>
    	</filter-mapping>

  5. #5
    Join Date
    Sep 2006
    Posts
    12

    Default Should be raised as bug

    I believe this should be raised as a bug:

    1. HiddenHttpMethodFilter reads via request.getParameter
    2. causing the ServletRequest.inputStream to be read
    3. FormHttpMessageConverter reads from servletRequest.getInputStream() which will be blank since it was already read.


    Did anybody raise this in JIRA currently?

  6. #6
    Join Date
    Sep 2006
    Posts
    12

    Default JIRA Issue

    Looks like this issue has been added related to : http://jira.springframework.org/browse/SPR-5628

  7. #7
    Join Date
    Aug 2009
    Posts
    1

    Default

    public boolean containsKey(java.lang.Object key)

    Returns true if this map contains at least one value for the specified key.

    Specified by:
    containsKey in interface java.util.Map<K,V>
    Overrides:
    containsKey in class java.util.AbstractMap<K,V>

    Parameters:
    key - key whose presence in this map is to be tested
    Returns:
    true if this map contains at least one value for the key, false otherwise.
    Throws:
    java.lang.ClassCastException - if the key is of an inappropriate type for this map.
    java.lang.NullPointerException - if the key is null and this map does not not permit null keys.

    Ab-circle-pro

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •