Marius Schmidt
Marius Schmidt

Reputation: 663

How to setup default success status codes for mapped HttpMethods Spring MVC @RestControllers?

Hi there Spring Gurus,

Currently we are annotating every mapped @RestController method with it's own success @ResponseStatus. I wonder, if there is a possibility for a global setup, based on the mapped @RequestMapping method. On Success we'd like to have:

If possible at all, what do we have to do?

Best regards, Marius

Upvotes: 0

Views: 1896

Answers (3)

sandeep verma
sandeep verma

Reputation: 149

Just use annotation on above your methods

@ResponseStatus(value=org.springframework.http.HttpStatus.OK)

@ResponseStatus(value=org.springframework.http.HttpStatus.CREATED)

@ResponseStatus(value=org.springframework.http.HttpStatus.OK)

@ResponseStatus(value=org.springframework.http.HttpStatus.OK)

@ResponseStatus(value=org.springframework.http.HttpStatus.NO_CONTENT)

Upvotes: 1

Shane Rowatt
Shane Rowatt

Reputation: 2105

You could extend the Spring @PostMapping and add the default @ResponseStatus i.e.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@PostMapping
@ResponseStatus(value = HttpStatus.CREATED)
public @interface CreatedPostMapping {
}

and then use that annotation instead of the spring ones e.g.

@CreatedPostMapping
public String create() { 
    return "blah"; 
}

Similarly for the other http verb annotations.

Upvotes: 0

NikolaB
NikolaB

Reputation: 4946

You could do it using a Filter:

public class ResponseStatusConverterFilter implements javax.servlet.Filter {

@Override
public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    chain.doFilter(request, response);

    switch (request.getMethod()) {
        case "GET": response.setStatus(200);
                    break;
        case "POST": response.setStatus(201);
                     break;
        ...
    }
}

And add filter in web.xml

<filter>
    <filter-name>responseStatusConverterFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>responseStatusConverterFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Just be careful with error handling because this could overwrite error response code. You should check response code before overwriting it (e.g check if it's some bad code like 500 or 404 and then do not set it to 200 or 201).

Another solution:

Create bean that extends HandlerInterceptorAdapter override

void postHandle(HttpServletRequest request,
                HttpServletResponse response,
                Object handler,
                ModelAndView modelAndView)
                throws Exception

and add logic similar to my first solution. Add bean definition to:

<mvc:interceptors>
   <bean class="com.your.web.ResponseConverterInterceptor" />
</mvc:interceptors>

Addendum: You will need to wrap HttpServletResponse with your class that extends HttpServletResponseWrapper :

public class StatusConvertingServletResponse extends HttpServletResponseWrapper {

    private int httpStatus;

    public StatusConvertingServletResponse(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void setStatus(int sc) {
        httpStatus = sc;
        super.setStatus(sc);
    }

    @Override
    public int getStatus() {
        return httpStatus;
    }
}

And use it like:

StatusConvertingServletResponse res = new StatusConvertingServletResponse((HttpServletResponse)response);
chain.doFilter(request, res);
if (res.getStatus() == 200) {
   res.setStatus(n);
}

Upvotes: 3

Related Questions