Servlet学习应该注意的几点

一、Servlet生命周期(即运行过程)

(1)初始阶段,调用init()方法

(2)响应客户请求阶段,调用service()方法。由service()方法根据提交方式不同执行doGet()或doPost()方法,其中service()方法判断了到底执行doGet()还是doPost()方法。

(3)终止阶段,调用destroy()方法。(服务器关闭)

Servlet生命周期中需要注意一下几点:

1)Servlet是长期贮存内存中的,当Servlet实例加载后,Servlet对象是长期保存在服务器内存中的。

2)Servlet被装载后,Web容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。而service()方法在每次客户端请求的时候都会调用。

3)HttpServlet中有两个Service()方法,HttpServlet中两个service()方法的区别:


  public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.service(arg0, arg1);
    }
  protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.service(arg0, arg1);
    }

A:其中第一种方法是由tomcat自动调用,它将接收的客户端请求转交给HttpServlet中的第二个service()方法,此保护类行的service()方法再把请求分发给doPost()、doGet()方法进行下一步处理。

B:HttpServlet类继承自GenericServlet,HttpServletRequest和HttpServletResponse分别继承自ServletRequest,ServletResponse,简单说,就是第一个方法是HttpServlet的,第二个方法是GenericServlet的,HttpServlet因为继承GenericServlet,所以继承了这个service()方法。

二、Servlet与九大内置对象

Servlet中如何获取JSP的九大内置对象

JSP对象 怎样获得 作用域
out response.getWriter() page
request service方法中的request参数 request
response service方法中的response参数 response
session request.getSession()函数 session
application this.getServletContext()函数 Application
exception new Throwable() page
page this page
pageContext new pageContext() page
config this.getSerletConfig()函数 page

将这九大对象分为

1、out对象和session对象

out对象是通过service()中的response的getWriter()方法获得,而response.getWriter()的返回的是PrintWriter类对象,而out对象是JspWriter类的实例,我们不妨对比一下两个类的方法。不难发现两个类都主要以print()方法为主。

session对象是通过service()中的request的getSession()方法获得,返回的对象就是对应了session实例。

代码示例(以out对象举例):

index.jsp代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP ‘index.jsp‘ starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>

  <body>
    <a href="Servlets/ServletDemo1"><h1>测试servletDemo1 servlet</h1></a>
  </body>
</html>

servletDemo1.java代码

package Servlets;

import java.io.IOException;
import java.io.PrintWriter;import javax.el.ELContext;
import javax.servlet.Servlet;import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import javax.servlet.jsp.JspWriter;public class ServletDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //resp.setHeader("Content-type", "text/html;charset=gbk");        //resp.setCharacterEncoding("gbk");
        System.out.println("测试ServletDemo1 doGet方法成功!");
        PrintWriter out=resp.getWriter();
        StringBuffer bf=new StringBuffer("<h1>这里是ServletDemo1 servlet!</h1>");
        out.print(bf);
    }

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

运行结果截图:

分析:绿色背景的代码实现了在servlet中获取out对象,并进行相应操作。但是我们发现通过out对象打印输出的汉字出现了乱码。

关于Servlet中的printWriter中文乱码的问题:

先分析原因:首先我们应该了解servlet中的两个参数request和response分别用来存储客户端发送的请求、储存服务器端返回的数据,而不管是储存还是取出都涉及到重新编码解析的问题,在这个过程如果存储和取出时使用的编码方式不同,势必会导致乱码。printWriter对象是通过response参数调用getWriter()函数获得的,作为响应的信息会在响应存储的时候进行编码的相关操作,而sun公司使用的码表是ISO8859-1之类的码表,而当浏览器显示响应结果时,也会去查码表,而中文的windows下的浏览器使用的一般是gbk或者gb2312,这样两次编码就不同。

解决方法:(两种)

(1)doxxx()方法中添加:response.setCharacterEncoding("gbk");

(2)doxxx()方法中添加:response.setHeader("content-type","text/html;charset=gbk");

上面代码中蓝色部分就是解决方法示例:

运行之后的结果截图:

当然,通过request的getSession()方法获得的session对象对于中文字符也可能出现乱码的问题,我们也可以通过添加:request.setCharaterEncoding("utf-8/gbk");

2、request对象和response对象

request和response对象都是通过service()方法传进的参数获得的,并且这两个参数直接被传入doGet()和doPost()的参数中。

  public void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.service(arg0, arg1);
    }

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

3、page对象、config对象和application对象

page对象代表了JSP转译的servlet实例对象,而在继承HttpServlet类的自定义Servlet类中,其当前实例对象在类中的表达,很明显使用this。所以page对象对应this完美。

config对象其实是通过自定义Servlet类的getSerletConfig()方法获取,自定义Servlet类继承自HttpServlet类,而getServletConfig()方法是HttpServlet类继承自其父类GenericServlet类而来,返回类型为ServletConfig对应了config的类。既然是调用其自定义Servlet类本身的getServletConfig()方法,则调用的写法应该是:this.getServletConfig();

application对象其实是通过自定义Servlet类的getSerletcontext()方法获取,自定义Servlet类继承自HttpServlet类,而getServletContext()方法是HttpServlet类继承自其父类GenericServlet类而来,返回类型为ServletContext对应了application的类。既然是调用其自定义Servlet类本身的getSerletcontext()方法,则调用的写法应该是:this.getSerletcontext()。

代码演示:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP ‘index.jsp‘ starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>

  <body>
  <%
  application.setAttribute("name", "小帅哥");
   %>
    <a href="Servlets/ServletDemo1"><h1>测试servletDemo1 servlet</h1></a>
  </body>
</html>

package Servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.Enumeration;

import javax.el.ELContext;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.VariableResolver;

public class ServletDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("content-type", "text/html;charset=gbk");
        ServletConfig sc=this.getServletConfig();
        Enumeration e=sc.getInitParameterNames();
       ServletContext application= this.getServletContext();
       String name=(String)application.getAttribute("name");
        PrintWriter out=resp.getWriter();
        out.print("<h2>name:"+name+"</h2>");
        out.print("<h1>初始化的参数名:</h1>");
        if(e.hasMoreElements()){
            out.print(e.nextElement()+" ");
        }else{
            out.print("该Servlet没有初始化参数!");
        }
        //req.getRequestDispatcher("/index1.jsp").forward(req, resp);
    }

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

运行结果截图:

4、pageContext对象和exception对象

pageContex是通过在Servlet中通过构造起自己构造的,构造的方法是:PageContext pc=new pageContext(),但是pageContext类是抽象类,通过直接new的方式可以获得pageContext对象,但是其中的方法需要覆盖重写才有意义,而重写的,里面的方法的实现大多都需要借助于其他内置对象,pageContext是一个集大成者的内置对象,他的出现就是能实现,一个内置对象能够访问其他内置对象。

PageContext pc=new PageContext() {

        @Override
        public void setAttribute(String arg0, Object arg1, int arg2) {
            // TODO Auto-generated method stub

        }

        @Override
        public void setAttribute(String arg0, Object arg1) {
            // TODO Auto-generated method stub

        }

        @Override
        public void removeAttribute(String arg0, int arg1) {
            // TODO Auto-generated method stub

        }

        @Override
        public void removeAttribute(String arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public VariableResolver getVariableResolver() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public JspWriter getOut() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ExpressionEvaluator getExpressionEvaluator() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ELContext getELContext() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public int getAttributesScope(String arg0) {
            // TODO Auto-generated method stub
            return 0;
        }

        @Override
        public Enumeration<String> getAttributeNamesInScope(int arg0) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Object getAttribute(String arg0, int arg1) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Object getAttribute(String arg0) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Object findAttribute(String arg0) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void release() {
            // TODO Auto-generated method stub

        }

        @Override
        public void initialize(Servlet arg0, ServletRequest arg1, ServletResponse arg2, String arg3, boolean arg4, int arg5,
                boolean arg6) throws IOException, IllegalStateException, IllegalArgumentException {
            // TODO Auto-generated method stub

        }

        @Override
        public void include(String arg0, boolean arg1) throws ServletException, IOException {
            // TODO Auto-generated method stub

        }

        @Override
        public void include(String arg0) throws ServletException, IOException {
            // TODO Auto-generated method stub

        }

        @Override
        public void handlePageException(Throwable arg0) throws ServletException, IOException {
            // TODO Auto-generated method stub

        }

        @Override
        public void handlePageException(Exception arg0) throws ServletException, IOException {
            // TODO Auto-generated method stub

        }

        @Override
        public HttpSession getSession() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ServletContext getServletContext() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ServletConfig getServletConfig() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ServletResponse getResponse() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public ServletRequest getRequest() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Object getPage() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public Exception getException() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void forward(String arg0) throws ServletException, IOException {
            // TODO Auto-generated method stub

        }
};

exception对象是一个异常对象,当一个JSP页面发生异常时就会产生这个对象,这个对象在Servlet中对应着Throwable类,调用的方法是:Throwable tb=new Throwable();而Throwable类的子类有Exception。几乎不使用这个。

三、Servlet路径跳转(假设在index.jsp页面进行跳转)

Servlet中有两种方式获得转发对象(RequestDispatcher):一种是通过HttpServletRequest的getRwquestDispatcher()方法获得,一种是通过ServletContext的getRequestDispatcher()方法获得。重定向的方法只有一种:HttpServletResponse的sendRedirect()方法。这三种方法的参数都是一个URL形式的字符串,但在使用相对路径或绝对路径上有所区别。

1、HttpServletResponse.sendRedirect(String):

(1)相对路径:

response.sendRedirect("index1.jsp");

(2)绝对路径:

response.sendRedirect("/index1.jsp");  其中"/"表示是项目根目录

response.sendRedirect(request.getContextPath()+"/index.jsp");  request.getContextPath()获得项目的根目录路径

(3)其他Web应用:

response.sendRedirect("http://www.baidu.com");

2、HttpServletRequest.getRequestDispatcher(String)

(1)相对路径:

HttpServletRequest.getRequestDispacher("../index1.jsp").forward(request,response);  其中“../”表明返回上层目录

HttpServletRequest.getRequestDispacher("index1.jsp").forward(request,response);

(2)绝对路径:

HttpServletRequest.getRequestDispacher("/index1.jsp").forward(request,response);  其中“/”表示根目录路径

HttpServletRequest.getRequestDispacher(request.getContextPath()+"/index1.jsp").forward(request,response);      request.getContextPath()获得项目的根目录路径

3、ServletContext.getRequestDispatcher():

(1)绝对路径:

ServletContext.getRequestDispatcher("/index1.jsp").forward(request,response);  其中“/”表示根目录路径

注意:HttpServletRequest.getRequestDispatcher(String)和ServletContext.getRequestDispatcher()的区别,其中ServletContext.getRequestDispatcher():只能使用绝对路径传值URL,且绝对路径必须是以"/"开头,其他都不行。而三种页面跳转只有HttpServletResponse.sendRedirect(String)可以实现非项目目录的跳转。

时间: 2024-08-13 11:18:57

Servlet学习应该注意的几点的相关文章

测试servlet学习笔记

操作方法: 1.新建工程: File-->new-->Java Project-->TestServlet(工程名称)-->Finish. 2.加载servlet-api.jar类包: TestServlet(右键)-->Build Path-->Configure Build Path-->Library -->Add External JAR Selection-->(浏览在tomcat的lib目录下找到servlet-api.jar选中后点击打开

SERVLET 学习笔记

SERVLET 学习笔记 一.Servlet基本定义 Servlet是服务器端上面运行的一段小的java程序,一个servlet就是一个简答的java类.通常servlet都是通过请求和返回的模式来被访问的,客户端通过resuest请求,servlet则通过response来返回需要的内容. 二.Tomcat容器等级 Tomcat容器等级分为四个等级,由内向外分别是:context容器àSERVLET容器àHOST(主机)容器àENGINE(引擎)容器.其中,CONTEXT容器,一个CONTEX

Servlet学习笔记(八)—— 自定义过滤器的编写改进:自定义实现FilterChain

笔记六中实现了三种过滤器:字符编码过滤.登录权限过滤.敏感词过滤,但是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤,最后response过滤,并且中间几项过滤的顺序不能动态改变.所以这里做个改进,实现一个过滤顺序的FilterChain. 多个Filter的执行顺序在这篇博文中得到很仔细的讲解,总结一点,多个过滤器的执行顺序是根据web.xml中不同<filter-mapping>的顺序来先后执行的,比如: <?xml version="1.0"

JavaWeb 后端 &lt;二&gt; 之 Servlet 学习笔记

JavaWeb 后端 <二> 之 Servlet 学习笔记 一.Servlet概述 1.什么是Servlet Servlet是一个运行在服务器端的Java小程序,通过HTTP协议用于接收来自客户端请求,并发出响应. 2.Servlet中的方法 public void service(ServletRequest req,ServletResponse res) throws ServletException,java.io.IOException ServletRequest req:代表着请

servlet学习(1)

1.Servlet是sun公司提供的一门用于开发动态web资源的技术. 2.Servlet在web应用的位置: 3.创建Servlet的三种方式: (1)实现servlet的接口 (2)继承GenericServlet,覆写service方法 (3)继承HttpServle,覆写doGet()或者doPost()等方法 注意: 1>GenericServlet实现了 Servlet 和ServletConfig接口. GenericServlet可以直接被一个servlet扩充,尽管它更为一般的

Servlet学习(2)

1.Servlet的生命的周   (1)当浏览器第一次访问Servlet时,服务器会根据浏览器访问的路径,在web.xml文件中找到该Servlet的全路径,然后利用反射去调用方法. (2)调用init()为Servlet作初始化工作 (3)调用doXxxxx()为浏览器响应 (4)如果浏览器再次访问相同的Servlet,直实现从服务端维护的Servlet实例集合中取得对应的实现,为浏览器响应 (5)同一个Servlet实例,在服务端只有一个 (6)服务器在决定销毁Servlet实例之前,调用d

Servlet学习笔记(七)—— JSP概述

1.Servlet两个缺陷: ①所有HTML标签必须包在Java字符串中,使得发送HTTP响应十分繁琐: ②所有文本和HTML标签都必须进行硬编码,即使对表示层做极其微小的修改,也需要重新编译. 2.注释: (1)JSP备注:<% %>,不会发送到浏览器,不能嵌套 (2)HTML备注:<!-- -->,不被容器处理,直接发送到浏览器,用途之一是标识JSP页面.在处理带有许多JSP片段的应用程序时,开发者通过查看HTML源代码,可以轻松查出某个HTML代码部分生成了那个JSP页面.

Servlet学习(三)Servlet编程实例-网站登录(修改版-增加数据库-附源码)

我们为刚才的那个示例Servlet学习(二)Servlet编程实例-网站登录添加上数据库,组成一个较为完整的登录功能. 在开始之前我们得首先了解下一些常用的java术语: PO(persistant object) 持久对象 在o/r 映射的时候出现的概念,如果没有o/r映射,就没有这个概念存在了. 通常对应数据模型(数据库),本身还有部分业务逻辑的处理. 可以看成是与数据库中的表相映射的java对象. 最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合. PO中应该不包含

第一个servlet学习

First Servlet(Servlet 学习日记) 前期准备 IDE: MyEclipse 2014 详细步骤 新建一个web project 右键新建servlet 3.代码详细如下 import java.io.DataOutputStream; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.H

Servlet学习的两个案例之网站访问次数的统计

一.统计次数的Servlet源码 package com.shanrengo; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.