URL重写之 解决浏览器cookie被禁止之后,session不能正常使用的问题

1. 浏览器禁用Cookie后的session处理:

1.2解决方案:URL重写

response.encodeRedirectURL(java.lang.String url)用于对重定向sendRedirect方法后的url地址进行重写。

response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写

1.3 案例:禁用Cookie后servlet共享Session中的数据

package com.zuoyueer.session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author Zuoyueer
 * Date: 2019/10/26
 * Time: 20:19
 * @projectName HomeWork
 * @description: 前提是浏览器进禁止了cookie.
 * 在超链接后面追加session的id, url = response.encodeURL(url);
 */
@WebServlet(urlPatterns = "/IndexServlet", name = "IndexServlet")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        //咋看之下这个servlet中没有使用到session,实际这句不能省略,因为必须在这里创建session对象,才能保证url后面有session的id,并且他们的id一样
        HttpSession session = request.getSession();
        writer.write("本网站有如下书籍:<br>");
        Set<Map.Entry<String, Book>> entries = DB.getAll().entrySet();
        for (Map.Entry<String, Book> entry : entries) {
            Book book = entry.getValue();
            String url = request.getServletContext().getContextPath() + "/BuyServlet?id=" + book.getId();
            System.out.println("前:"+url);//前:/day_25_Servlet_Web_exploded/BuyServlet?id=1
            //调用了该方法之后,url地址后面追加了session的id,这个id就是上面创建的那个session的id,如果不创建session对象,那么该方法没任何作用
            url = response.encodeURL(url);
            System.out.println("后:"+url);//后:/day_25_Servlet_Web_exploded/BuyServlet;jsessionid=191B10C0F2614D165306C62200FF4349?id=1
            writer.println(book.getName() + "<a href=\""+url+"\">购买</a><br>");
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

/**
 * 模拟数据库
 */
class DB {
    private static Map<String, Book> map = new LinkedHashMap<>();

    static {
        map.put("1", new Book("1", "javaee开发"));
        map.put("2", new Book("2", "spring开发"));
        map.put("3", new Book("3", "hibernate开发"));
        map.put("4", new Book("4", "struts开发"));
        map.put("5", new Book("5", "ajax开发"));
    }

    public static Map<String, Book> getAll() {
        return map;
    }
}

/**
 * 模拟javaBean
 */
class Book implements Serializable {
    private String id;
    private String name;

    public Book() {
    }

    public Book(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

package com.zuoyueer.session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Zuoyueer
 * Date: 2019/10/26
 * Time: 20:43
 * @projectName HomeWork
 * @description: 前提是浏览器进禁止了cookie.
 *  在请求重定向的时候,在url后面追加session的id,  String url = response.encodeRedirectURL(request.getContextPath() + "/ListCartServlet");
 */
@WebServlet(urlPatterns = "/BuyServlet", name = "BuyServlet")
public class BuyServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String id = request.getParameter("id");
        //获得要买的书
        Book book = DB.getAll().get(id);
        //注意,这里不再是创建session,而是获取之前在IndexServlet中创建的session对象,因为超链接请求的url后面带有session的id
        HttpSession session = request.getSession();
        //下面这种存储数据的方式非常的妙,避免多次每次访问都创建list集合,导致覆盖上一次请求的数据
        List<Book> list = (List) session.getAttribute("list");
        if (list == null) {
            //只有第一次访问的时候才创建list集合,其他的时候直接session域中获取
            list = new ArrayList<Book>();
            session.setAttribute("list", list);
        }
        //session中添加书
        list.add(book);
        //请求重定向的url后面追加session的id
        String url = response.encodeRedirectURL(request.getContextPath() + "/ListCartServlet");
        System.out.println(url);///day_25_Servlet_Web_exploded/ListCartServlet;jsessionid=191B10C0F2614D165306C62200FF4349
        //重定向
        response.sendRedirect(url);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

package com.zuoyueer.session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @author Zuoyueer
 * Date: 2019/10/26
 * Time: 21:38
 * @projectName HomeWork
 * @description: 显示session的中的数据信息
 */
@WebServlet(urlPatterns="/ListCartServlet", name="ListCartServlet")
public class ListCartServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        //获取之前的session对象
        HttpSession session = request.getSession();
        List<Book> list = (List) session.getAttribute("list");
        if (list==null||list.size()==0){
            writer.write("对不起,你还没有购买任何商品!");
            return;
        }
        writer.write("您买过如下商品:<br>");
        for(Book book : list){
            writer.write(book.getName()+"<br>");
        }
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

总结: url重写可以就是在url后面添加或者隐藏参数,满足需要的功能,本文使用了两种方法重写url,使得超链接和重定向的url后面带上了session的id,保证浏览器在禁止了cookie的情况下也能正常使用session.

另外我想强调的是,request.getSession()方法不一定是创建session对象: 只有客户端没有jsessionid或者服务端没有jsessionid所对应的session对象的时候,才会创建. 万万不可自以为第一次请求的时候创建,这种认知是不准确的!甚至可以说是错误的!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值