Servlet

Servlet

一、C/S和B/S架构
1.1 C/S

是指客户端/服务器。

优点:显示效果比较好,不用下载界面内容等。

缺点:每次更新需要下载客户端才能使用。

应用场景:一般应用于大型软件、游戏等。

1.2 B/S

是指浏览器/服务器。

优点:打开浏览器即可访问,更新只是在服务器上进行。

缺点:显示效果没有C/S好。

应用场景:基本上企业应用都会使用此架构。

二、服务器

注意:web服务器的作用是将程序员编写的web项目加载并运行。由于编写的web项目不能独立运行,而需要放入到web服务器加载运行,所以web项目中没有main方法。

三、Tomcat服务器
3.1 目录结构

许可证:表示当前软件是否可以使用,是否可以商用的许可。

常见的有Apache License。

bin:可执行文件。

conf:配置文件。server.xml是服务器的配置,用得最多。

lib:tomcat运行需要的jar包。

logs:日志文件。

webapps:可运行的web项目。(自己写的项目也是放到此处)ROOT是默认项目,如果把自己的项目放入ROOT中,那么自己项目也可以成为默认项目。实际在企业开发中,会删除掉ROOT里面的内容,或者将自己的项目放入其中。

work:主要是将JSP转换成servlet代码放入其中。

3.2启动和停止

tomcat的启动有两种方式:

  1. catalina.bat run 是通过控制台(命令行)直接启动,会显示日志和错误信息,关掉该窗口(也可以使用ctrl+C)即为停止。
  2. startup.bat 是通过后台运行的方式启动,需要通过shutdown.bat停止。(如果停止不了,需要关闭进程)

访问方式:本机访问可以通过打开浏览器输入:http://localhost:8080或者http://127.0.0.1:8080,如果其他人要访问,可以使用服务器ip:8080访问。

修改端口号可以在conf/server.xml中修改。默认为8080

#####3.3 HTTP协议

HTTP超文本传输协议。

基于请求和响应模式,无状态

三次握手和四次挥手

三次握手(three-way handshaking)

1.背景:TCP位于传输层,作用是提供可靠的字节流服务,为了准确无误地将数据送达目的地,TCP协议采纳三次握手策略。

2.原理:

1)发送端首先发送一个带有SYN(synchronize)标志地数据包给接收方。

2)接收方接收后,回传一个带有SYN/ACK标志的数据包传递确认信息,表示我收到了。

3)最后,发送方再回传一个带有ACK标志的数据包,代表我知道了,表示’握手‘结束。

四次挥手(Four-Way-Wavehand)

**1.意义:**当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。

2.原理:

1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手

长连接和短连接:

短连接是每次请求和响应都会建立连接和断开连接。

长连接是指多次请求和响应基于一次连接。在HTTP协议中,1.1版本使用的长连接,在规定时间内,可以完成多次请求和响应,超时断开。

四、Servlet的使用
4.1 Servlet接口、GenericServlet、HTTPServlet的关系

Servlet接口中包含5个方法,关键方法是init、destory、service。如果实现此接口需要实现5个方法,比较麻烦。

GenericServlet实现了Servlet接口,并对init、destory等方法提供了简单实现。如果继承此类只需要实现service方法即可。

HTTPServlet专注于HTTP协议。继承了GenericServlet,并重写了service方法。将其请求和响应强转成HTTP协议类型。并且对service方法进行了分发处理。然后定义了doGet、doPost等一系列的分发处理方法。这些方法内容都是直接报错,强制要求子类继承时必须要重写这些方法。(一般重写doGet和doPost方法即可)

4.2 Servlet创建和配置

继承HttpServlet并实现方法。

public class FirstServlet extends HttpServlet{
    public FirstServlet(){
        System.out.println("create FirstServlet");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("Hello, doGet");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("Hello, doPost");
    }
}

Servlet 2.5版本以及之前的配置,主要配置在web.xml中。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- 给Servlet类配置名字-->
    <servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>com.qf.day10.servlet.FirstServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>


    <!-- 给Servlet名字绑定路径-->
    <servlet-mapping>
        <servlet-name>FirstServlet</servlet-name>
        <url-pattern>/fs</url-pattern>
    </servlet-mapping>
</web-app>

Servlet3.0之后简化了配置,可以使用注解配置。

@WebServlet(value = "/ts", loadOnStartup = 2) // Servlet3.0以上的版本才支持
public class ThirdServlet extends HttpServlet{
    public ThirdServlet(){
        System.out.println("create ThirdServlet");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("ThirdServlet, doGet");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("ThirdServlet, doPost");
    }
}

Servlet默认是在第一次访问的时候创建并初始化对象。

但是可以通过配置loadOnStartup来改变此设定,以达到启动服务器就创建的目的。

默认是-1,如果配置为0或者正数,按照数字从小到大顺序来创建对象。

五、request和response的使用
5.1 request的使用

request是封装用户请求的对象。包含请求头和请求正文(具体内容参考请求报文)

常用的方法有两个:

getParameter(String name);通过表单提交的name属性名称获取对应的值。

setCharacterEncoding(String charset);设置POST请求的编码格式,因为默认是使用ISO-8859-1接收数据。

注意:GET方法在tomcat8.0后默认使用UTF-8编码,如果是8.0之前还是需要转码,如果不是使用 tomcat服务器,根据具体情况确定是否需要转码。

@WebServlet("/login.do")
public class LoginServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("正在接收数据:");
        String username = request.getParameter("username"); //接收表单name为username的数据
        // GET方式的转码
        // Tomcat8.0以后默认设置本来就是UTF-8,不需要转码,所以一般针对8.0之前的版本
//        username = new String(username.getBytes("ISO-8859-1"), "UTF-8");
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("正在接收数据:");
        request.setCharacterEncoding("utf-8"); // 转码
        String username = request.getParameter("username"); //接收表单name为username的数据
        System.out.println(username);
    }
}

index.html

注意:此处action属性中的路径应该写login.do而不能写/login.do,前面有/表示绝对路径,需要加上工程名称,正确的写法应该是/day11/login.do,但是并不能保证工程名称一定叫day11,所以应该使用动态方式(后面讲解)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
    <form method="get" action="login.do">
        <input type="text" name="username" placeholder="用户名"/>
        <input type="submit" value="提交"/>
    </form>
</body>
</html>
5.2 response的使用

response用来封装服务器对客户端的响应。通常会输出html页面内容。

常见的方法有两个:

getWriter():得到向页面输出的输出对象。

setContentType(String type):设置响应的内容类型和文本字符集。

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("正在接收数据:");
    request.setCharacterEncoding("utf-8"); // 转码
    String username = request.getParameter("username"); //接收表单name为username的数据

    // 设置响应的类型和字符集
    response.setContentType("text/html;charset=utf-8");
    // 得到向页面响应输出的对象
    PrintWriter out = response.getWriter();

    out.println("<!DOCTYPE html>");
    out.println("<html>");
    out.println("<head>");
    out.println("<meta charset=\"UTF-8\"/>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h1>当前用户为:"+username+"</h1>");
    out.println("</body>");
    out.println("</html>");
}
六、重定向和请求转发【重点】
6.1 重定向

在servlet中需要跳转到其他的页面或者servlet中,可以使用重定向方式。

该方式特点如下:

  1. 地址栏地址会变化。
  2. 至少有两次请求。
  3. 多次请求直接request对象不会共享,所以不会共享request对象中的数据。
  4. 可以跳转到站外。
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("正在接收数据:");
    request.setCharacterEncoding("utf-8"); // 转码
    String username = request.getParameter("username"); //接收表单name为username的数据
    String password = request.getParameter("password");
    // 登录的逻辑
    if (username.equals("zhangsan")&&password.equals("123456")){
        // 登录成功
        // 重定向到成功servlet(相当于页面上的<a>标签被点击)
        response.sendRedirect("success.html");
    }else{
        // 登录失败
        response.sendRedirect("fail.html");
    }
}
6.2 请求转发

在servlet中需要跳转到其他的页面或者servlet中,可以使用请求转发方式。

该方式特点如下:

  1. 属于服务器的行为。
  2. 只是一次请求。
  3. 地址栏地址不会发生改变。
  4. 请求对象会进行多次传递,所以可以使用request对象共享数据。
  5. 不能转发给站外。
  6. 可以手动存储数据以传递下一个servlet或页面。

注意:手动存储数据使用setAttribute(String key, Object obj);获取数据使用getAttribute(String key);返回Object类型,需要强制转换类型。

getAttribute(String key)和getParameter(String name)区别:

attribute是程序手动存储数据。所以有setAttribute方法和getAttribute方法。

parameter是容器封装请求对象时存储的数据,所以只有getParameter()方法。

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("正在接收数据:");
    request.setCharacterEncoding("utf-8"); // 转码
    String username = request.getParameter("username"); //接收表单name为username的数据
    String password = request.getParameter("password");
    // 登录的逻辑
    if (username.equals("zhangsan")&&password.equals("123456")){
        // 登录成功
        // 请求转发(将当前servlet的request和response对象传递下一个页面或者servlet)
        // 获得当前用户的余额(通常是查询数据库得到)
        String money = "3000元宝";
        // 将信息存入到request对象中,以键值对的形式
        request.setAttribute("money", money);
        request.getRequestDispatcher("success.html").forward(request, response);
    }else{
        // 登录失败
        response.sendRedirect("fail.html");
    }
}
七、综合案例

见day11_demo

八、Servlet生命周期

Servlet生命周期是指Servlet对象从创建到销毁的过程以及过程中所经历的内容。

创建(实例化new)-> 初始化(init) -> 服务(service)-> 销毁(destroy)

注意:初始化只会调用一次。服务是指Servlet接口中的方法。destroy方法是指在将要销毁之前调用的方法,一般用来释放资源等。

九、Servlet线程安全问题

Servlet是单实例,多线程

要解决线程安全问题,一般有以下方案:

  1. 实现SingleThreadModel接口,使Servlet在访问时变为单线程,那么必然安全,但是性能太低,不推荐

  2. 使用Synchronized代码块。

    使用技巧:尽量能不能使用全局变量就不要使用(推荐使用局部变量),或者仅使用只读的全局变量。从源头断绝线程安全问题出现。

十、状态管理

HTTP协议是无状态的,即服务器不会记录客户端的信息。每一次发送请求和响应都不会记录相关的客户端状态,因为这样可以提升访问速度。

如果需要进行状态管理,可以采用cookie或者session来处理。

cookie是指在客户端记录与服务器的交互信息,下一次再访问服务器,服务器会读取cookie中信息。cookie是一个txt文本,不安全。

session是指服务器会生成一个唯一的标识(sessionID),并将此表示发送到客户端,客户端会将其记录,下一次访问时服务器会访问此记录来确认是否访问过。相对安全。

10.1 编码和解码

cookie中不能保存中文,可以通过java.net.URLEncoder进行编码。然后使用java.net.URLDecoder中的decoder方法进行解码。

例如:张三,编码后会变成%E5%BC%A0%E4%B8%89,解码后又变成张三

public static void main(String[] args) throws Exception{
    String name = "张三";
    System.out.println("原来名称:" + name);
    String encodeString = URLEncoder.encode(name, "utf-8");
    System.out.println("编码后:" + encodeString);
    String decodeString = URLDecoder.decode(encodeString, "utf-8");
    System.out.println("解码后:" + decodeString);
}
10.2cookie的使用

首先,进入到IndexServlet来判断用户是否曾经登录并写入了cookie信息,如果没有则跳转到登录界面,如果写入了则跳转到首页。

@WebServlet("/index.html")
public class IndexServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 以发会员卡案例为示例
        // 获取用户请求中的cookies对象(让用户出示会员卡)
        Cookie[] cookies = request.getCookies();
        // 没有找到响应的cookies对象(用户告知没有会员卡)
        if (cookies == null){
            // 去登录,登录后保存cookie信息(去办理会员卡)
            response.sendRedirect("login.html");
        }else{ // 找到一些cookies信息(用户出示了一堆会员卡《五花八门》)
            String value = null;
            // 循环查找有没有正确的cookie信息(将用户出示的一堆会员卡进行翻找,看是否有我们下发的会员卡)
            for (Cookie cookie : cookies) {
                // 如果找到了对应的cookie信息(找到了我们下发的会员卡)
                if (cookie.getName().equals("day12_username")){
                    value = cookie.getValue(); // 记录该cookie信息(记录该会员卡信息)
                    break; // 跳出循环(不再翻找剩下的会员卡)
                }
            }
            // 如果最终没有记录正确的cookie信息,说明没有登录过(如果没有找到我们下发的会员卡)
            if (value == null){
                // 去登录,登录后保存cookie信息(去办理会员卡)
                response.sendRedirect("login.html");
            }else{
                // 如果找到了cookie信息,就跳转到首页并显示对应的信息(如果找到了会员卡,就允许直接进)
                request.setAttribute("currentUser", value); // 保存信息
                request.getRequestDispatcher("home.html").forward(request, response);
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

登录时,如果登录成功需要将用户信息写入到cookie。

@WebServlet("/login.do")
public class LoginServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 接收用户登录信息
        String name = request.getParameter("name");// 用户名
        String password = request.getParameter("password");// 密码
        if (name.equals("zhangsan") && password.equals("123456")){
            // 登录成功
            // 将登录成功的用户信息保存到cookie中
            Cookie cookie = new Cookie("day12_username", name); // 创建对象(注意不要中文)
            cookie.setPath("/day12"); //设置路径
            cookie.setMaxAge(60*60*12); // 设置生命周期,单位是秒,此处设置12小时
            response.addCookie(cookie); // 将cookie写入到响应对象中
            request.setAttribute("currentUser", name); // 保存信息
            request.getRequestDispatcher("home.html").forward(request, response);
        }else{
            response.sendRedirect("fail.html");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

cookie的优点:可以设置到期规则,相对简单。

cookie的缺点:不安全;数据大小有限制,一般默认大小不能超过4kb;容易被安全工具禁用了浏览器的cookie。

#####10.3 session的使用

session一般指一次会话。(一个浏览器与服务器之间的多次请求和响应的过程叫一次会话)

session的原理:由于cookie解决HTTP无状态问题时,会有三个缺点。通过session能够解决这三个问题。

使用session,会将数据保存在服务器,大小能够超出4kb的cookie的范围;将sessionID发送到客户端保存在cookie中,安全问题大大减低;即使浏览器禁用了cookie,也能够通过url重写(将sessionid以参数?的形式传递到服务器)的办法来解决。

session作为一个作用域,也具备setAttribute,getAttribute,removeAttribute三个常规操作方法。有效范围是一个会话范围。

会话的注销(销毁)的方法是session.invalidate();

LoginController

@WebServlet("/login.do")
public class LoginController extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 接收用户参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if (username.equals("zhangsan") && password.equals("123456")){
            // 登录成功
            HttpSession session = request.getSession(); // 获取当前session对象(类似于map)
            System.out.println("JSESSIONID=====" + session.getId());// 输出sessionID
            session.setAttribute("user", username); // 将登录成功的用户信息存入到session中
            response.sendRedirect("home.html");
        }else {
            // 登录失败
            response.sendRedirect("fail.html");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

LogoutController

@WebServlet("/logout.do")
public class LogoutController extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().invalidate(); // 注销当前用户
        response.sendRedirect("index.html"); // 跳转到登录界面
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

HomeJSP.java

@WebServlet("/home.html")
public class HomeJSP extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 判断用户是否登录,如果没有登录,则跳转到登录页面
        HttpSession session = request.getSession(); // 得到session
        String user = (String)session.getAttribute("user"); // 得到user信息
        // 如果没有得到信息,则未登录
        if (user == null){
            // 跳转登录页面
            response.sendRedirect("index.html");
        }else{
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.println("<h1>欢迎你,"+user+"</h1>");
            out.println("<a href=\"first.html\">First</a>");
            out.println("<a href=\"second.html\">Second</a>");
            out.println("<a href=\"logout.do\">注销</a>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
10.4 ServletContext

ServletContext指Servlet上下文,通常是指一个服务器(容器)对应的上下文。

作为一个作用域,范围是全局范围,即所有的用户皆可访问。

与前面学习的作用域比较范围大小如下:ServletContext > HttpSession > HttpServletRequest > PageContext

常见的方法:

getContextPath()得到上下文的名称,即工程的名称。

getRealPath("/")得到项目实际的完整路径。

十一、过滤器

过滤器是指在客户端与请求资源之间建立的一个拦截组件。它能够拦截用户的请求,并对请求进行一定的过滤分析,如果满足需求则放行,否则会被拦截并要求转向。

11.1 创建和配置

需要实现一个Filter接口。并将过滤逻辑写在doFilter方法中。

注意:doFiter方法中最后一定应该有过滤器链处理的代码。

@WebFilter("/*") // 配置过滤的路径
public class MyFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器开始过滤...");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 简单逻辑
        System.out.println("uri===" + request.getRequestURI());
        System.out.println("url===" + request.getRequestURL());
        String url = request.getRequestURI(); // 得到请求的路径
        // 判断请求路径是否合法
        if (url.endsWith("/first.do") ||
                url.endsWith("/first.html") ||
                url.endsWith("/index.html") ||
                url.endsWith("/") )
        {
            // 什么都不做(放行)
        }else{
            // 跳转到index页面
            response.sendRedirect("index.html");
            System.out.println("hello, world");
            return;
        }
        // 放过请求
        filterChain.doFilter(servletRequest, servletResponse); // 让过滤器链继续执行下一步过滤
    }

    @Override
    public void destroy() {

    }
}

Filter的配置一般有两种方式:

1.使用web.xml中配置

2.使用@WebFilter()注解配置

web.xml配置

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.qf.day13.utils.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注解配置见上面的案例代码

11.2 过滤器链

过滤器链是指在项目如果存在多个过滤器,则构成过滤器链,当发送请求时会依次通过过滤器链上的所有过滤的过滤。

当某一个过滤器禁止了请求的继续过滤时,一定要该代码后加上return。否则会引发Cannot call sendError…异常。

过滤器链优先级:

如果都在web.xml中配置,则按照配置的filter-mapping的顺序。

如果都使用注解配置,则按照类名称的字母顺序。

如果既有web.xml配置也有注解配置,web.xml配置的优先。

11.3 过滤器实际应用

在项目中过滤器一般应用在转码、认证、权限等场景。

下面代码演示了转码和认证的场景:

转码过滤器

@WebFilter("/*")
public class CharacterEncodingFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("开始转码...");
        servletRequest.setCharacterEncoding("utf-8"); // POST转码
        filterChain.doFilter(servletRequest, servletResponse); // 让过滤器链继续执行过滤
    }

    @Override
    public void destroy() {

    }
}

认证过滤器

@WebFilter("/*")
public class AuthFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("AuthFilter开始过滤...");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = request.getRequestURI(); // 得到请求的路径
        if (uri.endsWith("/login.do") ||
                uri.endsWith("/index.html")||
                uri.endsWith("/fail.html")){
            // url放行
        }else{
            HttpSession session = request.getSession();
            String user = (String) session.getAttribute("user");
            if (user == null){
                response.sendRedirect("index.html");
                return;
            }
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}
关于过滤器的想法和总结:
	因为过滤器起到拦截和放行的作用,所以在跳转时需要慎重,因为通过getURI获取的路径是request 携带的目标地址,过滤器是横在浏览器和目标地址之间的拦路虎,你需要符合你所写的过滤逻辑,搞清楚怎么样可以放过,怎么样会被拦截,发送到其他的界面。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值