在filter和servlet中的setCookie是否重复?

在filter和servlet中的setCookie是否重复?

在filter中设值了一个Cookie

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    String ticket = null;
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;
    if (null != request.getCookies()) {
        for (Cookie cookie : request.getCookies()) {
            if (Objects.equals(cookie.getName(), "Ticket_Granting_Ticket")) {
                ticket = cookie.getValue();
                break;
            }
        }
    }
    if (!Objects.equals(null, ticket)) {
        //进行用户校验,如果不是用户或非法用户,需要跳转到登录页面或者不需要登录页面
        chain.doFilter(req, resp);
        return;
    }

    ticket = request.getParameter("ticket");
    if (!Objects.equals(null, ticket) && !Objects.equals("", ticket.trim())) {
        response.addCookie(new Cookie("Ticket_Granting_Ticket", ticket));
        chain.doFilter(req, resp);
    } else {
        response.sendRedirect(server + "/ssoLogin?source=" + app);
    }
}

在Servlet中,如果请求路径是setCookie又加了一个Cookie

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (Objects.equals("/main", request.getServletPath())) {
        String domains = request.getParameter("domains");
        String ticket = request.getParameter("ticket");
        for (String server : domains.split(",")) {
            if (!Objects.equals(null, server) && !Objects.equals("", server.trim())) {
                setCookie(server, ticket);
            }
        }
        request.getRequestDispatcher("/WEB-INF/views/main.jsp").forward(request,response);
    } else if (Objects.equals("setCookie", request.getServletPath())) {
        String ticket = request.getParameter("ticket");
        response.addCookie(new Cookie("Ticket_Granting_Ticket", ticket));
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/text; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.write("ok");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != out) {
                out.close();
            }
        }
    }
}

按现在的逻辑是这样:

Webapp启动后被过滤器重新定向到Server的登录,Server中用户名和密码正确的话被重定向到WebApp1的main页面,此时先进入到WebApp1的filter中,这时候request域中的ticket是有值的,故进入if语句中新建了一个Cookie,经过filter接下来便进入到真正请求的WebApp1中Servlet中,请求地址是/main故通过线程池给Webapp2发送请求(此时的地址已经为setCookie,请求参数中有ticket)。。重点来了。。线程池中发的请求先经过Webapp2的filter,必定和上面一样先建一个Cookie出来,然后进入到Webapp2的Servlet中,此时因为请求地址为SetCookie故进入if语句内又建了一个Cookie。。所以这两Cookie是不是有点重复?请老师解答一下。。


p.s.

忍不住想吐槽一下老师的代码风格,看的很是难受,我还好,毕竟本省是C++程序员出生,被逼无奈才转Java。但是感觉这样写对小白很不友好啊。

e.g. 

domains.replace(source + ",", "").replace("," + source, "").replace(source, ""))

此处一连串的String.replace调用让人很晕,这最后到底出来的是个什么? 

有编程基础的知道Sout出来看看,小白的话只能自己臆想,自己猜。

e.g. 

((HttpServletRequest)request).getCookies());
((HttpServletResponse) response).sendRedirect(server + "/ssoLogin?source=" + app);

类似这样的代码,为什么不提前转出来后面直接调用,这如果少打个()对小白来说也很不友好,他们估计也不明白这两层括号是因为强转以后的优先级问题。

HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;

先转成这样再使用多好。  

第三点,老师讲这些代码的时候完全没讲清除到底是为什么这样写,垒代码到时快,给我感觉就是个人熟能生巧但是没考虑学生理解的问题,我建议可以先用流程图演示一下是怎么个顺序,让学生也有个思路逻辑。


个人一点捉见,望老师有所改进。

正在回答

登陆购买课程后可参与讨论,去登陆

2回答

登录成功后会在Filter中设置一次cookie,因为登录成功后跳转的地址是main,如下图所示。

http://img1.sycdn.imooc.com//climg/5bcd2c5f0001578413310427.jpg

所以会执行MainServlet的Servlet为main对应的代码,如下图所示。在这段代码中,如果domains和ticket都不为null,就调用syncCookie(也就是setCookie)去为另一个webapp设置cookie,去调用另一个webapp应该的MainServlet中的和setCookie相关的代码。所以不是为自己的应用设置cookie,而是为另一个web应用设置cookie

http://img1.sycdn.imooc.com//climg/5bcd2c8800015bb712970628.jpg

祝学习愉快!

好帮手慕珊 2018-10-21 14:23:03

你好!关于cookie设置的问题,是这样的,webapp1设置进入main后,会调用线程去执行webapp2的setcookie对应的内容,然后为webapp2设置cookie,不是再为webapp1再次设置一次cookie。同理,如果是webapp2先登录,也会调用线程去为webapp1设置cookie。

关于下面这个关于replace()方法使用的问题:

domains.replace(source + ",", "").replace("," + source, "").replace(source, ""))

domains的内容是http://127.0.01:8080,http://127.0.0.1:8081,使用replace()的作用是为了得到另一个app的地址。比如登录的是webapp1,那么希望最后得到的地址是webapp2的,就需要把domains中的http://127.0.0.1:8080,去掉。同理,如果是webapp2登录,就需要把webap2的地址连同都好一起去掉,去掉的方式就是用空字符串“”去替换这些内容。

非常抱歉为您带来了不好的学习体验,我们会将您的建议反馈给相关人员,也会在今后的课程优化中注意这些内容,让大家学习起来更加的顺利。如果还有哪些问题,可以继续在问答区提问。

祝学习愉快!

  • 提问者 渐丶忘 #1
    请求不是都先经过filter吗?先经过过滤器设置了一遍cookie,doFilter以后到了Servlet的setcookie对应的内容又设置了一遍。
    2018-10-21 14:28:11
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
从网页搭建入门Java Web2018版
  • 参与学习           人
  • 提交作业       1088    份
  • 解答问题       10205    个

如果你有Java语言基础,又想以后从事Java Web开发,那么本路径是你的不二选择!本路径从网页搭建开始入手,通过大量案例来学习Java Web基础。定能助你完成Java Web小白的蜕变!

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师