使用 ExceptionMapper 的自定义 HTTP 原因短语
Custom HTTP reason phrase using ExceptionMapper
我定义了以下异常映射器来处理自定义 HttpCustomException
package com.myapp.apis;
import com.myapp.apis.model.HttpCustomException;
import com.myapp.apis.model.HttpCustomExceptionStatusType;
import com.myapp.apis.model.HttpCustomNotAuthorizedException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class HttpCustomExceptionMapper implements ExceptionMapper <HttpCustomException> {
@Override
public Response toResponse (HttpCustomException e) {
Response response = Response.status (new HttpCustomExceptionStatusType (Response.Status.UNAUTHORIZED, e.getMessage ())).build ();
if (e instanceof HttpCustomNotAuthorizedException) {
response = Response.status (new HttpCustomExceptionStatusType (Response.Status.INTERNAL_SERVER_ERROR, e.getMessage ())).build ();
}
System.out.println ("HttpCustomExceptionMapper: " + response.getStatus () + ", " + response.getStatusInfo ().getReasonPhrase ());
return response;
}
}
当在代码中抛出 HttpCustomNotAuthorizedException
时,我可以在 catalina.out 中看到 toResponse
方法末尾定义的日志消息。因此,HttpCustomExceptionMapper class 在请求处理期间被调用。但是,在最终的响应中,我在客户端中看到,我只看到标准的 Not Authorized
消息,而不是我在 Response.
中设置的自定义消息
为什么会这样?
它显示的是标准回复,因为您没有为您的回复设置正文,您只是在设置状态。
您必须像这样传递自定义响应:
Response response = Response.status (Response.Status.INTERNAL_SERVER_ERROR).entity(CustomResponse).build ();
我对这个设计不太满意,但它会是这样的:
HttpCustomExceptionStatusType status = new HttpCustomExceptionStatusType (Response.Status.INTERNAL_SERVER_ERROR, e.getMessage ())
Response response = Response.status (status).entity(status).build ();
您应该注意,当前版本的 HTTP 协议 (HTTP/2) 根本不支持原因短语。它已从协议中删除。
因此,从 Tomcat 9.0 开始,已删除对发送原因短语的支持。在 Tomcat 7.0、8.5 中,默认关闭发送自定义原因短语的支持(可以通过 system property, org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER
). In 8.5 you also should set sendReasonPhrase="true"
on a Connector.
我定义了以下异常映射器来处理自定义 HttpCustomException
package com.myapp.apis;
import com.myapp.apis.model.HttpCustomException;
import com.myapp.apis.model.HttpCustomExceptionStatusType;
import com.myapp.apis.model.HttpCustomNotAuthorizedException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class HttpCustomExceptionMapper implements ExceptionMapper <HttpCustomException> {
@Override
public Response toResponse (HttpCustomException e) {
Response response = Response.status (new HttpCustomExceptionStatusType (Response.Status.UNAUTHORIZED, e.getMessage ())).build ();
if (e instanceof HttpCustomNotAuthorizedException) {
response = Response.status (new HttpCustomExceptionStatusType (Response.Status.INTERNAL_SERVER_ERROR, e.getMessage ())).build ();
}
System.out.println ("HttpCustomExceptionMapper: " + response.getStatus () + ", " + response.getStatusInfo ().getReasonPhrase ());
return response;
}
}
当在代码中抛出 HttpCustomNotAuthorizedException
时,我可以在 catalina.out 中看到 toResponse
方法末尾定义的日志消息。因此,HttpCustomExceptionMapper class 在请求处理期间被调用。但是,在最终的响应中,我在客户端中看到,我只看到标准的 Not Authorized
消息,而不是我在 Response.
为什么会这样?
它显示的是标准回复,因为您没有为您的回复设置正文,您只是在设置状态。 您必须像这样传递自定义响应:
Response response = Response.status (Response.Status.INTERNAL_SERVER_ERROR).entity(CustomResponse).build ();
我对这个设计不太满意,但它会是这样的:
HttpCustomExceptionStatusType status = new HttpCustomExceptionStatusType (Response.Status.INTERNAL_SERVER_ERROR, e.getMessage ())
Response response = Response.status (status).entity(status).build ();
您应该注意,当前版本的 HTTP 协议 (HTTP/2) 根本不支持原因短语。它已从协议中删除。
因此,从 Tomcat 9.0 开始,已删除对发送原因短语的支持。在 Tomcat 7.0、8.5 中,默认关闭发送自定义原因短语的支持(可以通过 system property, org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER
). In 8.5 you also should set sendReasonPhrase="true"
on a Connector.