文档章节

41 Servlet2 多线程

恋佳
 恋佳
发布于 2015/07/22 14:06
字数 1226
阅读 5
收藏 0
1 Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中。Servlet容器负责Servlet和客户的通信以及调用Servlet的方法,Servlet和客户的通信采用“请求/响应”的模式。
•Servlet可完成如下功能:
–创建并返回基于客户请求的动态HTML页面。
–创建可嵌入到现有 HTML 页面中的部分 HTML 页面(HTML 片段)。

–与其它服务器资源(如数据库或基于Java的应用程序)进行通信。


2 每一个Servlet都必须要实现Servlet接口,GenericServlet是个通用的、不特定于任何协议的Servlet,它实现了Servlet接口,而HttpServlet继承于GenericServlet,因此HttpServlet也实现了Servlet接口,所以我们定义的Servlet只需要继承HttpServlet父类即可。

3 Servlet接口中定义了一个service方法,HttpServlet对该方法进行了实现,实现方式就是将ServletRequest与ServletResponse转换为HttpServletRequest与HttpServletResponse

public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException {

        HttpServletRequest  request;
        HttpServletResponse response;
        
        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException("non-HTTP request or response");
        }
        service(request, response);
    }


4 转换完毕后,会调用HttpServlet类中自己定义的service方法,在该service方法中,首先获得到请求的方法名,然后根据方法名调用对应的doXXX方法,比如说请求方法为GET,那么就去调用doGet方法;请求方法为POST,那么就去调用doPost方法。

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
            
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);        
            
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
            
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }


5在HttpServlet类中所提供的doGet、doPost等方法都是直接返回错误信息,所以我们需要在自己定义的Servlet类中override这些方法


protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } else {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
        }
6 ServletRequest主要方法

•getAttribute 根据参数给定的属性名返回属性值
•getContentType 返回客户请求数据MIME类型
•getInputStream 返回以二进制方式直接读取客户请求数据的输入流
•getParameter 根据给定的参数名返回参数值
•getRemoteAddr 返回远程客户主机的IP地址(用于投票)
•getRemoteHost 返回远程客户主机名
•getRemotePort 返回远程客户主机的端口



7ServletResponse 主要方法

•getOutputStream 返回可以向客户端发送二进制数据的输出流对象ServletOutputStream
•getWriter 返回可以向客户端发送字符数据的PrintWriter对象
•getCharacterEncoding 返回Servlet发送的响应数据的字符编码
•getContentType 返回Servlet发送的响应数据的MIME类型
•setContentType 设置Servlet发送的响应数据的MIME类型


8 Servlet 何时被创建


默认情况下,当Web客户第一次请求访问某个Servlet时,Web容器创建这个Servlet的实例
•如果设置了<servlet>元素的<load-on-startup>子元素,Servlet容器在启动Web应用时,将按照指定的顺序创建并初始化这个Servlet。
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.test.servlet.HelloServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>


9某些Servlet在web.xml文件中只有<servlet>元素而没有<servlet-mapping>元素,这样我们就无法通过url地址的方式访问这个Servlet了,这种Servlet通常会在<servlet>元素中配置一个<load-on-startup>子元素,让容器在启动的时候自动加载该Servlet,并且调用其init方法完成一些全局性的初始化工作。


10 Servlet的多线程同步问题:Servlet本身是单实例的,这样当有多个用户同时访问某个Servlet时,会访问该唯一的Servlet实例中的成员变量,如果对成员变量进行写入操作,那就会导致Servlet的多线程问题,即数据不一致。

private String username;
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		 username = req.getParameter("username");
		
		//得到当前线程的名字
		System.out.println(Thread.currentThread().getName());
		
		//进行一些后端的业务处理
		try
		{
			Thread.sleep(10000);
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
		
		req.setAttribute("username", username);
		req.getRequestDispatcher("hello.jsp").forward(req, resp);
	}

11 解决Servlet多线程同步问题的最好方案:去除实例变量,使用局部变量

12 JSP与Servelet

JSP的优点是擅长于网页制作,生成动态页面,比较直观。JSP的缺点是不容易跟踪与排错。
•Servlet是纯Java语言,擅长于处理流程和业务逻辑。Servlet的缺点是生成动态网页不直观。






















© 著作权归作者所有

恋佳
粉丝 0
博文 76
码字总数 62107
作品 0
大连
私信 提问
java中关于SESSION创建的一个问题

当servlet中首次调用getSession()的之后,请求转发给另一个servlet,在另一个servlet中是怎么拿到这个Session的ID的?比如我在servlet1中,首次调用request.getSession() HttpSession sessio...

初来
2014/09/13
3.2K
3
Forward和Redirec两种转发的区别

一、概述 Forward和Redirect代表了两种请求转发方式:直接转发和间接转发。   直接转发方式(Forward),客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资...

懂得-奉献
2016/10/21
2
0
Response.sendRedirect()

一、用sendRedirect方法实现请求重定向 sendRedirect方法用于生成302响应码和Location响应头,从而通知客户端去重新访问Location响应头中指定的URL。 RedirectServlet.java import java.io....

KYZGJ
2014/04/14
0
0
Servlet中forward和include的区别

forward方法是把请求的内容转发到另外的一个servlet.而include是把另一个servlet处理过后的内容拿过来. 举例来说比如在servlet1打一句out.print("aaaa"),servlet2打上out.print("bbbb"),在s......

晨曦之光
2012/05/16
927
0
Servlet请求转发 RequestDispatcher接口

在Servlet中,利用RequestDispatcher对象,可以将请求转发给另外一个Servlet或JSP页面,甚至是HTML页面,来处理对请求的响应。 一,RequestDispatcher接口方法简介 1,RequestDispatcher对象...

crazyinsomnia
2009/12/23
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

Python应用:python链表示例

前言 python链表应用源码示例,需要用到python os模块方法、函数和类的应用。 首先,先简单的来了解下什么是链表?链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是...

python小白1
25分钟前
1
0
Source Insight加载源码

Source Insight是一个图形化的源代码查看工具(当然也可以作为编译工具)。如果一个项目的源代码较多,此工具可以很方便地查找到源代码自建的依赖关系。 1.创建工程 下图为Snort源代码的文件...

天王盖地虎626
26分钟前
0
0
nginx-rtmp-module的缺陷分析(二)

nginx-rtmp-module使用指令push和pull来relay媒体流数据,以便分布式部署服务。 当nginx-rtmp-module作为边缘服务器(一般不会向边缘服务器推流)时,使用pull从源服务器获取媒体流数据,俗称...

YoungSagit
27分钟前
0
0
代理模式

保护代理和虚拟代理 虚拟代理 把开销大的操作等到需要执行创建的时候再去执行创建 var myImage = +function () { var imgNode = document.createElement('img'); docume......

莫西摩西
34分钟前
1
0
从国企到互联网,程序员六年四段工作经历,一份被很多 HR都 刷掉的简历!

程序员,六年,四段工作经历,这也许是一份会被很多 HR 刷掉的简历。 从学生时代至今,我经历了两次大的方向转型和一次大的技术转型: 从偏理论推导的数学科学到重工程实践的计算机学科,从「...

我最喜欢三大框架
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部