【发布时间】:2016-12-22 15:13:34
【问题描述】:
任务:我不想在我的堆栈跟踪中接收一般的HTTP 500 Internal Server Error 和在客户端同样可怕的堆栈跟踪,我希望看到我的自定义消息和另一个状态码(例如403),开发人员会更清楚发生了什么。并向用户添加一些关于异常的消息。
以下是我的应用程序中更改的几个类:
服务器部分:
AppException.class - 我所有的服务器响应异常(在返回给客户端之前)我想转换成这个异常。有点标准的实体类
public class AppException extends WebApplicationException {
Integer status;
/** application specific error code */
int code;
/** link documenting the exception */
String link;
/** detailed error description for developers */
String developerMessage;
public AppException(int status, int code, String message, String developerMessage, String link) {
super(message);
this.status = status;
this.code = code;
this.developerMessage = developerMessage;
this.link = link;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getDeveloperMessage() {
return developerMessage;
}
public void setDeveloperMessage(String developerMessage) {
this.developerMessage = developerMessage;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public AppException() {
}
public AppException(String message) {
super("Something went wrong on the server");
}
}
ÀppExceptionMapper.class - 将我的 AppException 映射到 JAX-RS 运行时,而不是标准异常,客户端接收 AppException。
@Provider
public class AppExceptionMapper implements ExceptionMapper<AppException> {
@Override
public Response toResponse(AppException exception) {
return Response.status(403)
.entity("toResponse entity").type("text/plain").build();
}
}
ApplicationService.class- 我的服务类抛出 AppException
@Path("/applications")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface ApplicationService {
@DELETE
@Path("/deleteById")
void deleteById(@NotNull Long id) throws AppException;
}
客户部分:
ErrorHandlingFilter.class- 我的 AppException 响应捕获器。在这里,我想根据状态将每个 Response 异常转换为另一个异常。
@Provider
public class ErrorHandlingFilter implements ClientResponseFilter {
private static ObjectMapper _MAPPER = new ObjectMapper();
@Override
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
if(responseContext.hasEntity()) {
Error error = _MAPPER.readValue(responseContext.getEntityStream(), Error.class);
String message = error.getMessage();
Response.Status status = Response.Status.fromStatusCode(responseContext.getStatus());
AppException clientException;
switch (status) {
case INTERNAL_SERVER_ERROR:
clientException = new PermissionException(message);
break;
case NOT_FOUND:
clientException = new MyNotFoundException(message);
break;
default:
clientException = new WhatEverException(message);
}
throw clientException;
}
}
}
}
PermissionException.class - 我想要转换 AppException 的异常,如果它带有 500 状态代码。
public class PermissionException extends AppException{
public PermissionException(String message) {
super("403 - Forbidden. You dont have enough rights to delete this Application");
}
Integer status;
/** application specific error code */
int code;
/** link documenting the exception */
String link;
/** detailed error description for developers */
String developerMessage;
public PermissionException(int status, int code, String message, String developerMessage, String link) {
super(message);
this.status = status;
this.code = code;
this.developerMessage = developerMessage;
this.link = link;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getDeveloperMessage() {
return developerMessage;
}
public void setDeveloperMessage(String developerMessage) {
this.developerMessage = developerMessage;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public PermissionException() {}
}
ApplicationPresenter.class- 一段 UI 逻辑,我想要处理 ErrorHandlingFilter 抛出的 PermissionException。
@SpringPresenter
public class ApplicationPresenter implements ApplicationView.Observer {
@Resource
private ApplicationService applicationService;
@Resource
private UiEnvironment uiEnvironment;
@Override
public void deleteSelectedApplication(BeanItemGrid<Application> applicationGrid) {
try {
applicationService.deleteById(applicationGrid.getSelectedItem().getId());
} catch (PermissionException e) {
e.printStackTrace();
e.getMessage();
} catch (AppException e2) {
}
}
}
如何解决我的问题?我仍然收到标准500 InternalErrorException.
几乎将整个问题再更新一次!
【问题讨论】:
-
当您拥有 ExceptionMapper 时,您不会自己捕获异常,而是让框架在 HTTP 请求上调用资源方法时捕获它。 (我不太明白你上一堂课是做什么的;是客户端代码吗?)
-
@gsl 是的,我只是想显示我在哪里捕获了我的异常。我试图做同样的事情,但没有 PermissionExceptionMapper。类,只是只有 PermissionException。它没有工作(
-
好吧,您不必在自己的代码中捕获它。 (除了一个测试程序,但我不明白这有什么意义。)
-
@gsl 如果您将您的第一条评论作为帖子的答案,我将接受它作为答案。看来我完全错误地理解了 ExctentionMapper 的概念
-
为什么不处理从 ApplicationService / PermissionExceptionMapper 收到的响应?
标签: java spring rest jersey jax-rs