SpringMVC实现基于一个变量的多个控制器的自定义响应
Spring MVC realise a custom response for multiple controllers based on a variable
我有几个控制器,像这样用@RequestMapping 注释:
@RequestMapping(value = "/group/{groupName}", method = RequestMethod.GET)
public ResponseEntity<List<Group>> getGroups(@PathVariable("groupName") String groupName) {...}
附带说明一下,请求和响应是用 jackson 进行(反)序列化的。
只有存在与另一台服务器的连接时,才能处理这些请求。如果该连接中断,我会收到一条通知并想重试建立连接。这样做时我想 return 状态码 500.
最干净的方法是什么?
-- 在此先感谢您。
编辑:
我想我没说清楚。当我失去与其他服务器的 JMX 连接时,我的控制器仍然可以工作,并且 return 错误代码在 200 范围内。
但是当我收到连接已丢失的通知时,我希望所有控制器都return 500。
我能想到的唯一方法是在每个控制器中设置一个标志并使用 if 语句。
public class Connector {
void handleNotification(Notification notification, Object handback) {
switch (notification.getType()) {
case "jmx.remote.connection.failed":
IS_CONNECTED = false;
break;
// ... other cases
}
}
}
控制器看起来像这样:
@RequestMapping(value = "/group/{groupName}", method = RequestMethod.GET)
public ResponseEntity<List<Group>> getGroups(@PathVariable("groupName") String groupName) {
if (connector.IS_CONNECTED) {
// ...
} else {
// return 500
}
}
此代码将是多余的且无法维护,所以我希望有人对此有更好的解决方案。
您有多种方法来处理 spring 中的错误。
例如,您可以抛出一个错误并在您的控制器中添加一个 @ExceptionHandler
。
如果您想要更多的全局异常处理,您可以使用 class 上的 @ControllerAdvice
来定义将异常绑定到错误代码的方式。
您也可以 return 一个 ResponseEntity。在这个class中你可以设置你想要的http状态return。例如,如果出现问题,您可以 return a new ResponseEntity<List<Group>>(HttpStatus.INTERNAL_SERVER_ERROR);
定义您的 HandlerExceptionResolver
或使用现有的另一种方式。
您将在此博客上找到更多信息 post : https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
我的问题的解决方案是添加一个过滤器。
这里的关键是如果应该返回错误,则不要将响应放回过滤器链中。
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 就完成了。
我有几个控制器,像这样用@RequestMapping 注释:
@RequestMapping(value = "/group/{groupName}", method = RequestMethod.GET)
public ResponseEntity<List<Group>> getGroups(@PathVariable("groupName") String groupName) {...}
附带说明一下,请求和响应是用 jackson 进行(反)序列化的。
只有存在与另一台服务器的连接时,才能处理这些请求。如果该连接中断,我会收到一条通知并想重试建立连接。这样做时我想 return 状态码 500.
最干净的方法是什么?
-- 在此先感谢您。
编辑:
我想我没说清楚。当我失去与其他服务器的 JMX 连接时,我的控制器仍然可以工作,并且 return 错误代码在 200 范围内。
但是当我收到连接已丢失的通知时,我希望所有控制器都return 500。
我能想到的唯一方法是在每个控制器中设置一个标志并使用 if 语句。
public class Connector {
void handleNotification(Notification notification, Object handback) {
switch (notification.getType()) {
case "jmx.remote.connection.failed":
IS_CONNECTED = false;
break;
// ... other cases
}
}
}
控制器看起来像这样:
@RequestMapping(value = "/group/{groupName}", method = RequestMethod.GET)
public ResponseEntity<List<Group>> getGroups(@PathVariable("groupName") String groupName) {
if (connector.IS_CONNECTED) {
// ...
} else {
// return 500
}
}
此代码将是多余的且无法维护,所以我希望有人对此有更好的解决方案。
您有多种方法来处理 spring 中的错误。
例如,您可以抛出一个错误并在您的控制器中添加一个 @ExceptionHandler
。
如果您想要更多的全局异常处理,您可以使用 class 上的 @ControllerAdvice
来定义将异常绑定到错误代码的方式。
您也可以 return 一个 ResponseEntity。在这个class中你可以设置你想要的http状态return。例如,如果出现问题,您可以 return a new ResponseEntity<List<Group>>(HttpStatus.INTERNAL_SERVER_ERROR);
定义您的 HandlerExceptionResolver
或使用现有的另一种方式。
您将在此博客上找到更多信息 post : https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
我的问题的解决方案是添加一个过滤器。
这里的关键是如果应该返回错误,则不要将响应放回过滤器链中。
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 就完成了。