response.getWriter()


response.getWriter()

參考:

https://blog.csdn.net/zp2605811855/article/details/91852527

在學習Spring Security 圖形驗證碼時, 碰到了一個有趣的問題, 其實還是誤解

自定義filter來處理圖形驗證碼

public class ValidateCodeFilter extends OncePerRequestFilter {
    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
    @Autowired
    AuthenticationFailureHandler failureHandler;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (isProtectedUrl(request)) {
            try {
                validateCode(new ServletWebRequest(request));
            } catch (ValidateCodeException e) {
                failureHandler.onAuthenticationFailure(request,response,e);
            }
        }
        filterChain.doFilter(request, response);
    }
    
private void validateCode(ServletWebRequest servletWebRequest) throws ServletRequestBindingException {
        //通過session key獲取到對應的imageCode
        ImageCode codeInSession = (ImageCode) sessionStrategy
                .getAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);
        //從request獲取name為imageCode的值
        String codeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "imageCode");
        if (StringUtils.isBlank(codeInRequest)){
            throw new ValidateCodeException("驗證碼不能為空");
        }else if (ObjectUtils.isEmpty(codeInSession)){
            throw new ValidateCodeException("驗證碼不存在");
        }else if (codeInSession.isExpire()){
            //如果驗證碼超時失效,刪除session中存的值
            sessionStrategy.removeAttribute(servletWebRequest, ValidateController.SESSION_KEY_IMAGE_CODE);
            throw new ValidateCodeException("驗證碼過期");
        }else if (!StringUtils.equalsIgnoreCase(codeInSession.getCode(),codeInRequest)){
            throw new ValidateCodeException("驗證碼不正確");
        }
        //如果校驗通過, 刪除session中的imageCode
        sessionStrategy.removeAttribute(servletWebRequest,ValidateController.SESSION_KEY_IMAGE_CODE);
    }

自定義的failureHandler

public class FailureHandler implements AuthenticationFailureHandler {
    @Autowired
    private ObjectMapper mapper;
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(mapper.writeValueAsString(exception.getMessage()));
    }
}

發現驗證碼即使錯誤了也能正常訪問, 這就讓我百思不得其解

后來發現原來少寫了return;

            } catch (ValidateCodeException e) {
                failureHandler.onAuthenticationFailure(request,response,e);
                return;
            }

可是為什么必須加這個return呢? response.getWriter().write()不是直接將字符串寫到

頁面中了嗎?

下面這段時源碼中注解

Calling flush() on the PrintWriter commits the response.
Either this method or {@link #getOutputStream} may be called to write the body, not both.

可以大概理解為將內容flush到response 的響應體中, 只有當reponse處理完畢后返回給用戶時才會寫入到頁面,並不是直接輸出到頁面, 所以這里必須要加return 否則reponse放行了, 就會到下一個filter中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM