Spring MVC realise a custom response for multiple controllers based on a variable

时间:2015-06-26 09:29:01

标签: java spring spring-mvc web controller

I have a couple of controllers, annotated with @RequestMapping like so:

@RequestMapping(value = "/group/{groupName}", method = RequestMethod.GET)
public ResponseEntity<List<Group>> getGroups(@PathVariable("groupName") String groupName) {...}

As a side note the requests and responses are (de)serialized with jackson.

Those requests can only be handled if there exists a connection to another server. If that connection breaks I receive a notification and want to retry establishing the connection. While doing that I want to return status code 500.

What is the cleanest way to do so?

-- Thank you in advance.

EDIT:

I think I wasn't clear. When I lose the JMX connection to the other server my controllers will still work and return error codes in the 200-range.

But when I receive a notification that the connection has been lost I want all controllers to return 500.

The only way I could think of to achieve that would be to set a flag and use an if-statement in each controller.

public class Connector {
    void handleNotification(Notification notification, Object handback) {
            switch (notification.getType()) {
                case "jmx.remote.connection.failed":
                    IS_CONNECTED = false;
                    break;
                // ... other cases
            }
    }
}

The Controller would look like this:

@RequestMapping(value = "/group/{groupName}", method = RequestMethod.GET)
public ResponseEntity<List<Group>> getGroups(@PathVariable("groupName") String groupName) {
    if (connector.IS_CONNECTED) {
        // ...
    } else {
        // return 500
    }
}

This code would be redundant and unmaintainable so I hope someone has a better solution for this.

2 个答案:

答案 0 :(得分:0)

You have several way to handle error in spring.

For example, you can just throw a error and add a @ExceptionHandler in your controller.

If you want to have more global exception handling, you can use the @ControllerAdvice on a class to define the way to bind your exception on error code.

It's also possible to return a ResponseEntity as you make. In this class you can set the http status you want to return. for example, if something goes wrong, you can return a new ResponseEntity<List<Group>>(HttpStatus.INTERNAL_SERVER_ERROR);

The other way it to define your HandlerExceptionResolver or use a existing one.

You will find more information on this blog post : https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

答案 1 :(得分:0)

我的问题的解决方案是添加过滤器。

这里的关键是如果应该返回错误,不要将响应放回过滤器链中。

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        if (isConnectionBroken(DaemonConnector.connectionStatus)) {
            //set error 500 because daemon connection lost
            response.sendError(500, "Connection to Daemon failed: " + DaemonConnector.connectionStatus);
        } else {
            // everything works fine, just continue in the filter chain
            chain.doFilter(req, res);
        }
    }

然后我只是将过滤器添加到web.xml中,我就完成了。