Tomcat 使用ExceptionMapper的自定义HTTP原因短语

Tomcat 使用ExceptionMapper的自定义HTTP原因短语,tomcat,jax-rs,http-status-codes,exceptionmapper,Tomcat,Jax Rs,Http Status Codes,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

我已经定义了以下异常映射器来处理定制的
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;
  }
}
package com.myapp.api;
导入com.myapp.api.model.HttpCustomException;
导入com.myapp.api.model.HttpCustomExceptionStatusType;
导入com.myapp.api.model.HttpCustomNotAuthorizedException;
导入javax.ws.rs.core.Response;
导入javax.ws.rs.ext.ExceptionMapper;
导入javax.ws.rs.ext.Provider;
@提供者
公共类HttpCustomExceptionMapper实现ExceptionMapper{
@凌驾
公众响应(HTTPE){
Response-Response=Response.status(新的HttpCustomExceptionStatusType(Response.status.UNAUTHORIZED,e.getMessage()).build();
if(HttpCustomNotAuthorizedException的实例){
response=response.status(新的HttpCustomExceptionStatusType(response.status.INTERNAL_SERVER_ERROR,e.getMessage()).build();
}
System.out.println(“HttpCustomExceptionMapper:+response.getStatus()+”,“+response.getStatusInfo().getReasonPhase());
返回响应;
}
}
当代码中抛出
HttpCustomNotAuthorizedException
时,我可以在catalina.out中看到
toResponse
方法末尾定义的日志消息。因此,HttpCustomExceptionMapper类在请求处理期间被调用。但是,在最终的响应中,我在客户机中只看到标准的
未授权的
消息,而没有看到我在响应中设置的自定义消息


为什么会发生这种情况?

它显示的是标准响应,因为您没有为响应设置正文,而只是设置了状态。 您必须按如下方式传递自定义响应:

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对发送自定义原因短语的支持在默认情况下是关闭的(可以通过,
org.apache.coyote.USE_custom_STATUS_MSG_In_HEADER
启用)。在8.5中,您还应该在一个.

上设置
sendReasonPhase=“true”
,可能是因为您正在传播标准
e.getMessage()
。尝试添加自定义字符串以进行测试。在代码中引发异常时,我已设置了自定义字符串。我可以确认
e.getMessage()
根据代码中的print语句提供了一个自定义字符串。非常感谢。这正是问题所在!感谢您指出还可以配置响应主体:)