Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MockMvc引发内部异常,而不是返回带有4xx状态代码的响应_Java_Spring Boot_Testing_Mockmvc - Fatal编程技术网

Java MockMvc引发内部异常,而不是返回带有4xx状态代码的响应

Java MockMvc引发内部异常,而不是返回带有4xx状态代码的响应,java,spring-boot,testing,mockmvc,Java,Spring Boot,Testing,Mockmvc,我正在尝试使用MockMvc编写JwtTokenVerifier测试 当我试图请求一些带有无效Auth头的API时:它不会返回带有4xx状态码的响应,而是抛出一个内部异常(在我的例子中是AuthException)。 我应该在测试中看到这个异常吗 或者我需要做点什么来得到回应 (对值“”和“123”的测试成功,但对带有AuthException(io.jsonwebtoken.MalformedJwtException:JWT字符串必须正好包含2个句点字符)的“承载QEWQWEQWE”测试失败。

我正在尝试使用MockMvc编写JwtTokenVerifier测试

当我试图请求一些带有无效Auth头的API时:它不会返回带有4xx状态码的响应,而是抛出一个内部异常(在我的例子中是AuthException)。 我应该在测试中看到这个异常吗 或者我需要做点什么来得到回应

(对值“”和“123”的测试成功,但对带有AuthException(io.jsonwebtoken.MalformedJwtException:JWT字符串必须正好包含2个句点字符)的“承载QEWQWEQWE”测试失败。找到的:0)

测试:

JwtTokenVerifier筛选器:

public class JwtTokenVerifier extends OncePerRequestFilter {

    //DI

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader(jwtConfig.getAuthorizationHeader());
        if (StringUtils.isEmpty(authHeader) || !authHeader.startsWith(jwtConfig.getTokenPrefix())) {
            logger.warn("Invalid Authorization header - '" + authHeader + "'");
            filterChain.doFilter(request, response);
            return;
        }
        try {
            Claims body = getTokenBodyFromAuthHeader(authHeader);

            String username = body.getSubject();

            AuthUser userDetails = userDetailsService.loadUserByUsername(username);
            CustomTokenBasedAuthentication authentication = new CustomTokenBasedAuthentication(userDetails);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            userContext.setCurrentPrincipal(authentication);
        } catch (JwtException e) {
            logger.error("During authentication (token verification) exception occurred", e);
            throw new AuthException("auth error");
        }
        filterChain.doFilter(request, response);
    }

    ...
}
ApiExceptionHandler:

@ControllerAdvice(basePackages = {"bac9h.demoapp"})
public class ApiExceptionsHandler {

    ...

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(AuthException.class)
    @ResponseBody
    public String onAuthException(AuthException e) {
        return "401 error: " + e.getMessage();
    }
}

看起来一切都连接好了,工作正常,但是JWT解析器发现您提供的承载令牌甚至不是JWT的有效格式,所以它引发了异常


我建议以正确的格式创建JWT,但这在您的应用程序上下文中没有意义,无法测试您试图验证的行为。试试。

我意识到我的apiExceptionHandler不适用于过滤器

:

根据JavaServlet规范的规定,过滤器总是在调用servlet之前执行。现在,@ControllerAdvice只对在DispatcherServlet中执行的控制器有用。因此,使用过滤器并期望调用@ControllerAdvice或在本例中调用@ExceptionHandler是不会发生的

为了得到适当的响应,我需要手动提供异常处理程序

@ControllerAdvice(basePackages = {"bac9h.demoapp"})
public class ApiExceptionsHandler {

    ...

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(AuthException.class)
    @ResponseBody
    public String onAuthException(AuthException e) {
        return "401 error: " + e.getMessage();
    }
}
@Before
public void setup() {
    this.mockMvc = MockMvcBuilders.standaloneSetup(statusController)
         .setControllerAdvice(new ExceptionController())
        .build();