网站的自动刷新及Servlet线程安全

2017-11-20 12:04:20

    相关方法,response.setHeader("refresh",3);

    建立RefreshServlet文件,相应代码为

package com.nosay.servlet;

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 java.io.IOException;

@WebServlet(name = "RefreshServlet",urlPatterns = "/refresh")
public class RefreshServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.setHeader("refresh","3");
        response.getWriter().print("3秒后自动刷新");
    }
}

    打开浏览器访问,发现它在3秒后自动刷新,测试成功.

    但是如果我们希望其在3秒后自动跳转到另外一个界面的时候,应该怎么处理呢?

    我们只需要稍微改变一下代码,即可实现相应的功能了.

    相关代码如下:

package com.nosay.servlet;

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 java.io.IOException;

@WebServlet(name = "RefreshServlet",urlPatterns = "/refresh")
public class RefreshServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.setHeader("refresh","3;url='https://www.baidu.com'");
        response.getWriter().print("3秒后自动刷新");
    }
}

    这样,三秒过后就自动跳转到百度去了.

    在实际的开发中,三秒后自动刷新这样的功能是不会直接写到servlet中的,这些代码通常会写到jsp中.

    在根目录下建立refresh.jsp文件,相关内容如下:

<%--
  Created by IntelliJ IDEA.
  User: nosay
  Date: 17-11-20
  Time: 上午11:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%=request.getAttribute("message")%>
</body>
</html>

    RefreshServlet相关内容如下

package com.nosay.servlet;

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 java.io.IOException;

@WebServlet(name = "RefreshServlet",urlPatterns = "/refresh")
public class RefreshServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String message = "<meta http-equiv=\"refresh\" content=\"3;url=/member.jsp\">3秒后会自动跳转到首页,如果没有跳转,请点击<a href='/member.jsp'>跳转链接 </a>";
        request.setAttribute("message",message);
        request.getRequestDispatcher("/refresh.jsp").forward(request,response);
        RefreshDemo(response);
    }

    private void RefreshDemo(HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        response.setHeader("refresh","3;url='https://www.baidu.com'");
        response.getWriter().print("3秒后自动刷新");
    }
}

    打开相应的url地址,测试成功.

    Servlet线程安全问题

    什么是线程安全?

    Servlet的线程安全相关

    当多个客户端并发访问同一个Servlet的时候,web服务器会为每一个客户端的访问创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内部如果访问了同一个共享资源的话,就可能引发线程安全问题.

    例子:

    建立ThreadServlet文件,内容为

package com.nosay.servlet;

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 java.io.IOException;

@WebServlet(name = "ThreadServlet",urlPatterns = "/thread")
public class ThreadServlet extends HttpServlet {
    int i = 0;
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        i ++;
        try {
            Thread.sleep(5*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(i+"");
    }
}

    此时,分别打开两个浏览器访问,运行结果全部为2,并不像我们想像的那样,一个是1一个是2.

    解决,可以使用同步代码块,如下所示

package com.nosay.servlet;

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 java.io.IOException;

@WebServlet(name = "ThreadServlet",urlPatterns = "/thread")
public class ThreadServlet extends HttpServlet {
    int i = 0;
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        synchronized (this)
        {
            i ++;
            try {
                Thread.sleep(5*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write(i+"");
        }

    }
}