如何处理 Spring 引导重定向到 /error?
How to handle Spring Boot's redirection to /error?
我遇到了与 中相同的问题,使用 Spring Boot 1.3.0 并且没有用 @RestController
注释我的控制器,只是 @Path
和@Service
。正如该问题中的 OP 所说,
this is, to me, anything but sensible
我也不明白为什么他们会把它重定向到 /error。而且很可能是我遗漏了一些东西,因为我只能给客户返回404s或200s。
我的问题是他的解决方案似乎不适用于 1.3.0,因此我有以下请求流程:假设我的代码抛出 NullPointerException
。它将由我的 ExceptionMapper
s
之一处理
@Provider
public class GeneralExceptionMapper implements ExceptionMapper<Throwable> {
private static final Logger LOGGER = LoggerFactory.getLogger(GeneralExceptionMapper.class);
@Override
public Response toResponse(Throwable exception) {
LOGGER.error(exception.getLocalizedMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
我的代码 return 是 500,但它没有将其发送回客户端,而是尝试将其重定向到 /error。如果我没有其他资源,它会发回 404。
2015-12-16 18:33:21.268 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 1 * Server has received a request on thread http-nio-8080-exec-1
1 > GET http://localhost:8080/nullpointerexception
1 > accept: */*
1 > host: localhost:8080
1 > user-agent: curl/7.45.0
2015-12-16 18:33:29.492 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 1 * Server responded with a response on thread http-nio-8080-exec-1
1 < 500
2015-12-16 18:33:29.540 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 2 * Server has received a request on thread http-nio-8080-exec-1
2 > GET http://localhost:8080/error
2 > accept: */*
2 > host: localhost:8080
2 > user-agent: curl/7.45.0
2015-12-16 18:33:37.249 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 2 * Server responded with a response on thread http-nio-8080-exec-1
2 < 404
客户端 (curl):
$ curl -v http://localhost:8080/nullpointerexception
* STATE: INIT => CONNECT handle 0x6000572d0; line 1090 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* Trying ::1...
* STATE: CONNECT => WAITCONNECT handle 0x6000572d0; line 1143 (connection #0)
* Connected to localhost (::1) port 8080 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x6000572d0; line 1240 (connection #0)
* STATE: SENDPROTOCONNECT => DO handle 0x6000572d0; line 1258 (connection #0)
> GET /nullpointerexception HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.45.0
> Accept: */*
>
* STATE: DO => DO_DONE handle 0x6000572d0; line 1337 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x6000572d0; line 1464 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x6000572d0; line 1474 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 404 Not Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Content-Length: 0
< Date: Wed, 16 Dec 2015 17:33:37 GMT
<
* STATE: PERFORM => DONE handle 0x6000572d0; line 1632 (connection #0)
* Curl_done
* Connection #0 to host localhost left intact
所以它总是一个 404。除非我有这样的 /error 资源,那又怎样?我应该 return 做什么?那时我所拥有的只是对 /error 的 GET 请求。而且我不希望那些额外的请求消耗资源并污染我的日志。
我错过了什么?如果没有,我应该如何处理我的异常处理?
您可以将球衣 属性 ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR
设置为 true
。
Whenever response status is 4xx
or 5xx
it is possible to choose between sendError
or setStatus
on container specific Response implementation. E.g. on servlet container Jersey can call HttpServletResponse.setStatus(...)
or HttpServletResponse.sendError(...)
.
Calling sendError(...)
method usually resets entity, response headers and provide error page for specified status code (e.g. servlet error-page
configuration). However if you want to post-process response (e.g. by servlet filter) the only way to do it is calling setStatus(...)
on container Response object.
If property value is true the method Response.setStatus(...)
is used over default Response.sendError(...)
.
Type of the property value is boolean
. The default value is false
.
您只需在 ResourceConfig
子类构造函数中调用 property(key, value)
即可设置 Jersey 属性。
我遇到了与 @RestController
注释我的控制器,只是 @Path
和@Service
。正如该问题中的 OP 所说,
this is, to me, anything but sensible
我也不明白为什么他们会把它重定向到 /error。而且很可能是我遗漏了一些东西,因为我只能给客户返回404s或200s。
我的问题是他的解决方案似乎不适用于 1.3.0,因此我有以下请求流程:假设我的代码抛出 NullPointerException
。它将由我的 ExceptionMapper
s
@Provider
public class GeneralExceptionMapper implements ExceptionMapper<Throwable> {
private static final Logger LOGGER = LoggerFactory.getLogger(GeneralExceptionMapper.class);
@Override
public Response toResponse(Throwable exception) {
LOGGER.error(exception.getLocalizedMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
我的代码 return 是 500,但它没有将其发送回客户端,而是尝试将其重定向到 /error。如果我没有其他资源,它会发回 404。
2015-12-16 18:33:21.268 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 1 * Server has received a request on thread http-nio-8080-exec-1
1 > GET http://localhost:8080/nullpointerexception
1 > accept: */*
1 > host: localhost:8080
1 > user-agent: curl/7.45.0
2015-12-16 18:33:29.492 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 1 * Server responded with a response on thread http-nio-8080-exec-1
1 < 500
2015-12-16 18:33:29.540 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 2 * Server has received a request on thread http-nio-8080-exec-1
2 > GET http://localhost:8080/error
2 > accept: */*
2 > host: localhost:8080
2 > user-agent: curl/7.45.0
2015-12-16 18:33:37.249 INFO 9708 --- [nio-8080-exec-1] o.glassfish.jersey.filter.LoggingFilter : 2 * Server responded with a response on thread http-nio-8080-exec-1
2 < 404
客户端 (curl):
$ curl -v http://localhost:8080/nullpointerexception
* STATE: INIT => CONNECT handle 0x6000572d0; line 1090 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* Trying ::1...
* STATE: CONNECT => WAITCONNECT handle 0x6000572d0; line 1143 (connection #0)
* Connected to localhost (::1) port 8080 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x6000572d0; line 1240 (connection #0)
* STATE: SENDPROTOCONNECT => DO handle 0x6000572d0; line 1258 (connection #0)
> GET /nullpointerexception HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.45.0
> Accept: */*
>
* STATE: DO => DO_DONE handle 0x6000572d0; line 1337 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x6000572d0; line 1464 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x6000572d0; line 1474 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 404 Not Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Content-Length: 0
< Date: Wed, 16 Dec 2015 17:33:37 GMT
<
* STATE: PERFORM => DONE handle 0x6000572d0; line 1632 (connection #0)
* Curl_done
* Connection #0 to host localhost left intact
所以它总是一个 404。除非我有这样的 /error 资源,那又怎样?我应该 return 做什么?那时我所拥有的只是对 /error 的 GET 请求。而且我不希望那些额外的请求消耗资源并污染我的日志。
我错过了什么?如果没有,我应该如何处理我的异常处理?
您可以将球衣 属性 ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR
设置为 true
。
Whenever response status is
4xx
or5xx
it is possible to choose betweensendError
orsetStatus
on container specific Response implementation. E.g. on servlet container Jersey can callHttpServletResponse.setStatus(...)
orHttpServletResponse.sendError(...)
.Calling
sendError(...)
method usually resets entity, response headers and provide error page for specified status code (e.g. servleterror-page
configuration). However if you want to post-process response (e.g. by servlet filter) the only way to do it is callingsetStatus(...)
on container Response object.If property value is true the method
Response.setStatus(...)
is used over defaultResponse.sendError(...)
.Type of the property value is
boolean
. The default value isfalse
.
您只需在 ResourceConfig
子类构造函数中调用 property(key, value)
即可设置 Jersey 属性。