【问题标题】:Spring boot and Jersey, can't make ExceptionMapper workSpring Boot 和 Jersey,不能让 ExceptionMapper 工作
【发布时间】:2018-08-14 13:38:15
【问题描述】:

我正在使用 Spring boot + Spring Security + Jersey。

我一直在尝试做一些事情,即 ExceptionMapper 发生 Unathorized 错误,但它似乎不起作用。但是,我完成的其他映射器工作得很好。

这是我的代码:

未经授权的异常:

package com.ulises.usersserver.rest.exceptionsmappers;

import com.ulises.usersserver.rest.dto.ErrorDTO;
import com.ulises.usersserver.rest.dto.ErrorDTOBuilder;

import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import static com.ulises.usersserver.constants.Constants.REQUEST_ERROR_UNATHORIZED;

public class NotAuthorizedMapper implements ExceptionMapper<NotAuthorizedException> {
    @Override
    public Response toResponse(NotAuthorizedException e) {
        final ErrorDTO errorDTO = ErrorDTOBuilder.builder()
                .message(REQUEST_ERROR_UNATHORIZED)
                .build();
        return Response.status(Response.Status.UNAUTHORIZED)
                .type(MediaType.APPLICATION_JSON_TYPE)
                .entity(errorDTO)
                .build();
    }
}

其他完美运行的自定义映射器:

package com.ulises.usersserver.rest.exceptionsmappers;

import com.ulises.usersserver.rest.dto.ErrorDTO;
import com.ulises.usersserver.rest.dto.ErrorDTOBuilder;
import com.ulises.usersserver.services.exceptions.UserNotFoundException;

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import static com.ulises.usersserver.constants.Constants.REQUEST_ERROR_USER_DOESNT_EXIST;

public class UserNotFoundExceptionMapper implements ExceptionMapper<UserNotFoundException> {
    @Override
    public Response toResponse(UserNotFoundException e) {
        final ErrorDTO errorDTO = ErrorDTOBuilder.builder()
                .message(REQUEST_ERROR_USER_DOESNT_EXIST)
                .build();
        return Response.status(Response.Status.NOT_FOUND).entity(errorDTO).build();
    }
}

它们当然是在 Jersey 的配置中注册的:

@Bean
public ResourceConfig jerseyConfig() {
    final ResourceConfig resourceConfig = new ResourceConfig();
                      ...
    resourceConfig.register(NotFoundMapper.class);
    resourceConfig.register(NotAuthorizedMapper.class);
                      ...

    return resourceConfig;
}

我似乎无法映射其他异常,例如 InternalServerErrorException(我设法通过这样做来映射这个异常 ExceptionMapper&lt;Exception&gt;,这对我来说看起来不太正确。

有人知道为什么会这样吗?我在这里检查了所有可能的问题,但没有一个能解决这个问题。

提前致谢。

【问题讨论】:

  • NotAuthorizedException 在哪里被抛出?
  • 我真的不知道,如果用户的登录信息有误,是 Spring Security 抛出的。但是,这并不重要。据我了解,通过注册该映射器 Jersey 应该去那里做我想让它做的事情,就像它在这里所说的那样:makeinjava.com/…

标签: java spring-boot exception jersey


【解决方案1】:

好的,Jersey 似乎无法控制 Spring Security 的异常。

解决这个问题的方法(不得不进行大量研究)是覆盖 AuthenticationEntryPoint 中的方法,如果用户未获得授权,S-Security 使用该方法返回 401 响应。

所以我创建了以下实现该接口的类:

public class CustomEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response, AuthenticationException authException) throws IOException {
        JSONObject json = new JSONObject();
        json.put("Message", "You don't have access to view this section. Please, log in with an authorized account.");
        response.addHeader("Content-Type", "application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().println(json);
    }
}

然后只需将此配置添加到 S-Security 以将此类用作entry point

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().authenticationEntryPoint(new CustomEntryPoint());
         ..... any other config you had .....
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-29
    • 2018-12-24
    • 1970-01-01
    • 2015-03-14
    • 2018-10-23
    • 2014-03-11
    • 1970-01-01
    相关资源
    最近更新 更多