Results 1 to 3 of 3

Thread: Failure for ModelAttribute DataBinding on a x-www-form-urlencoded PUT

  1. #1
    Join Date
    Dec 2009
    Posts
    5

    Post Failure for ModelAttribute DataBinding on a x-www-form-urlencoded PUT

    I have discovered an issue with Spring data binding where a real PUT request doesn't bind correctly to a ModelAttribute whereas a hidden one does (ie, POST with parameter _method=put) when using a HiddenHttpMethodFilter in my servlet.

    My controller class is:

    Code:
    @Transactional(readOnly = false)
    @RequestMapping(value = "/group/{id}",method = RequestMethod.PUT)
    public @ResponseBody Group update(@ModelAttribute Group group) {
    	return directoryService.persist(group);
    }
    	
    @ModelAttribute
    public Group setup(@PathVariable String id) {
    	return StringUtils.isEmpty(id) ? new Group() : directoryService.get(Group.class, id);
    	}
    When I send an x-www-form-urlencoded POST request with _method=put along with any parameters to modify the group, the values are correctly mapped to the ModelAttribute Group. However, when I send a x-www-form-urlencoded PUT request with the same parameters to modify the group, the group is unchanged showing none of the parameters have been bound to the ModelAttribute object fetched by setup.

    It is my understanding that in HTTP, a PUT is allowed to wrap entities like a POST and should therefore bind data the same as a POST within spring.

    I considered that the HiddenHttpMethodFilter might be the issue and so added PUT as a method that should be wrapped:

    Code:
    	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    			throws ServletException, IOException {
    
    		String paramValue = request.getParameter(this.methodParam);
    		if (("POST".equals(request.getMethod()) || "PUT".equals(request.getMethod())) && StringUtils.hasLength(paramValue)) {
    			String method = paramValue.toUpperCase(Locale.ENGLISH);
    			HttpServletRequest wrapper = new HttpMethodRequestWrapper(method, request);
    			filterChain.doFilter(wrapper, response);
    		}
    ...
    but the appears to make no difference and instead points to an issue with the way data is bound for POSTs vs PUTs deeper within spring.

    Has anyone:
    1) experienced this before,
    2) has a solution, or
    3) has an explanation for why this is happening?

    Cheers,
    Luke

  2. #2
    Join Date
    Dec 2009
    Posts
    5

    Default

    I noticed that my modification to the HiddenHttpMethodFilter wasn't correct as I didn't actually set the method correctly on the wrapper.

    Code:
    		String paramValue = request.getParameter(this.methodParam);
    		if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
    			String method = paramValue.toUpperCase(Locale.ENGLISH);
    			HttpServletRequest wrapper = new HttpMethodRequestWrapper(method, request);
    			filterChain.doFilter(wrapper, response);
    		} else if ("PUT".equals(request.getMethod())){
    			HttpServletRequest wrapper = new HttpMethodRequestWrapper("PUT", request);
    			filterChain.doFilter(wrapper, response);
    		} else {
    			filterChain.doFilter(request, response);
    		}
    However even with this fix, the original request is still a PUT not a POST and the binding still doesn't happen.

  3. #3
    Join Date
    Nov 2010
    Posts
    1

    Unhappy Binding on RESTful PUT

    Hello all,

    I have the exact same problem. Spring should provide the behavior of binding to an @ModelAttribute for a PUT request as it does for POST, without needing the extra gymnastics of filters and hidden parameters! I was surprised it does not provide this out of the box.

    This is standard REST, and I should be able to send a PUT request to update my form data.

    Zeron

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
  •