Spring启动控制器问题

时间:2017-09-09 14:49:35

标签: spring servlets spring-boot servlet-filters

我正在使用过滤器来检查用户是否已连接(令牌有效),如果令牌不是有效的我设置了一个名为“error”的属性,其中包含错误的详细信息,这里是我的控制器

@RestController
public class HomeController {


@RequestMapping(value = "secure/info", method = RequestMethod.POST)

public Object login(@RequestBody User user,@RequestAttribute(name="error") AppError error)  {

    if(error!=null) return error ;
    return "information";

}

这是我的过滤器:

        @Override
        public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
                throws IOException, ServletException {

            final HttpServletRequest request = (HttpServletRequest) req;
            final HttpServletResponse response = (HttpServletResponse) res;
            final String authHeader = request.getHeader("authorization");

            if ("OPTIONS".equals(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);

                chain.doFilter(request, response);
            } else {

                if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                    AppError error = new AppError("0001","Invalid bearer token.");
                    request.setAttribute("error", error);
                    chain.doFilter(request, response);
                }

                final String token = authHeader.substring(7);

                try {
                    final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
                    request.setAttribute("claims", claims);
                } catch (final SignatureException e) {
                    AppError error = new AppError("0002","Invalid token signature.");
                    request.setAttribute("error", error);
                    chain.doFilter(request, response);
                }
                 catch (final ExpiredJwtException e) {
                     AppError error = new AppError("0003","Expired token.");
                     request.setAttribute("error", error);
                     chain.doFilter(request, response);

                 }

                 catch (final MalformedJwtException e) {
                     AppError error = new AppError("0004","Malformed token.");
                     request.setAttribute("error", error);
                     chain.doFilter(request, response);
                     //return ;
                 }



                chain.doFilter(req, res);
            }
        }

这是我得到的例外:

  

java.lang.IllegalStateException:无法在调用之后调用sendError()   已经做出回应         在org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:472)   〜[Tomcat的嵌入芯-8.5.16.jar:16年5月8日]         at org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotReadable(DefaultHandlerExceptionResolver.java:386)   〜[弹簧webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]         在 ...             ....         在com.inconso.LoginFilter.doFilter(LoginFilter.java:67)[classes /:na]

2 个答案:

答案 0 :(得分:2)

在第一次chain.doFilter(request, response);之后添加退货声明 - 早期退货方式

                if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                    AppError error = new AppError("0001","Invalid bearer token.");
                    request.setAttribute("error", error);
                    chain.doFilter(request, response);

                    // ADD a RETURN STATEMENT HERE
                }

OR(IF-ELSE Ladder Approach)

// START: MOVE THIS inside AN ELSE Block

                final String token = authHeader.substring(7);

                try {
                    final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
                    request.setAttribute("claims", claims);
                } catch (final SignatureException e) {
                    AppError error = new AppError("0002","Invalid token signature.");
                    request.setAttribute("error", error);
                    chain.doFilter(request, response);
                }
                 catch (final ExpiredJwtException e) {
                     AppError error = new AppError("0003","Expired token.");
                     request.setAttribute("error", error);
                     chain.doFilter(request, response);

                 }

                 catch (final MalformedJwtException e) {
                     AppError error = new AppError("0004","Malformed token.");
                     request.setAttribute("error", error);
                     chain.doFilter(request, response);
                     //return ;
                 }
// END: MOVE THIS inside AN ELSE Block

答案 1 :(得分:1)

在此条件为真的else块中:authHeader == null || !authHeader.startsWith("Bearer ")您正在调用chain.doFilter()两次。

一旦进入这个区块:

if (authHeader == null || !authHeader.startsWith("Bearer ")) {
    AppError error = new AppError("0001","Invalid bearer token.");
    request.setAttribute("error", error);
    chain.doFilter(request, response);
}

else区块结束时第二次:

else {

    ...

    chain.doFilter(req, res);
}

一旦足够,所以要么从else块的底部删除最后一个chain.doFilter(request, response),要么从该块中其他地方的if和catch子句中删除chain.doFilter(request, response)