3

I'm using Java 8, Tomcat 8, Spring-WebMVC 4.2.2.RELEASE, FasterXML 2.6.3.

I have the following method in my controller

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public void updateCurrentUserDetails(@RequestBody final UserDTO userDTO) {
    final UserWithId user = SecurityUtil.getCurrentUser();
    this.userAccountService.updateUserDetails(user.getUserId(), user.getUsername(), userDTO);
}

This method returns void which resolves in an empty (0 byte) response. However the clients connecting to the server always expect JSON reponses even, if its an empty response.

So I would like to configure Spring/Jackson to return {} (2 byte) in that case.

I already thought about returning new Object() everywhere in the calls that would return void otherwise but IMO this is a dirty soution and there must be something better.

2 Answers 2

11

There shouldn't be any need to do all that. You can just use a 204 response code, which is made for the situation you are describing. You don't even need the ResponseBody annotation, just use:

@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updateCurrentUserDetails(@RequestBody final UserDTO userDTO) {
    final UserWithId user = SecurityUtil.getCurrentUser();
    this.userAccountService.updateUserDetails(user.getUserId(), user.getUsername(), userDTO);
}

204 response code:

The 204 (No Content) status code indicates that the server has
successfully fulfilled the request and that there is no additional
content to send in the response payload body.

Sign up to request clarification or add additional context in comments.

1 Comment

While technically this is the right answer, it does not match the requirements. The sad truth is that the framework used by the clients is not capable of dealing with HTTP 204 or empty bodies. And the server is supposed to make up for it. But I'll keep nagging there of course.
4

Its quite easy.

Just add the following to your spring xml/java config

<mvc:interceptors>
    <bean class="de.st_ddt.util.VoidResponseHandlerInterceptor" />
</mvc:interceptors>

And add this class to your classpath

public class VoidResponseHandlerInterceptor extends HandlerInterceptorAdapter {

    private static final String voidResponse = "{}";

    @Override
    public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler,
            final ModelAndView modelAndView) throws IOException {
        // Returned void?
        if (!response.isCommitted()) {
            // Used ModelAndView?
            if (modelAndView != null) {
                return;
            }
            // Access static resource?
            if (DefaultServletHttpRequestHandler.class == handler.getClass()) {
                return;
            }
            response.setStatus(200);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            try (final Writer writer = response.getWriter()) {
                writer.write(voidResponse);
            }
            response.flushBuffer();
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.