• 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中

  • 相关阅读:
    如何修改mysql root密码
    【STL】list基础(转)
    时间控制timer settimeout setinterval
    刷新ArrayCollection的显示控件
    需要科普的网站
    flex 拖拽数据
    常用的资源网站
    as3 性能优化
    对象池
    Bitmap与Bitmapdata
  • 原文地址:https://www.cnblogs.com/kikochz/p/12897407.html
Copyright © 2020-2023  润新知