Servlet 学习笔记
servlet基础
初步认识servlet
在JSP开发过程中,人们不断地将JSP进行模式化的分离处理。模式化的处理将网页中的表示、业务处理、逻辑处理层进行了很好的分离,增强了程序的可扩展性及可维护性。最初的JSP开发模式为JSP+JavaBean,称为Model1模式。在建立中、小型的网站中,这种模式应用的比较多。JSP+ Servlet+ JavaBean则慢慢演变成了Model2模式,它在实际中更为广泛地得到应用。一般的大型网站中,都采用此技术进行构建。
Servlet是一种独立于平台和协议的服务器端的Java应用,可以生成动态的Web页面。与传统的CGI(计算机图形接口)和许多其他类似CGI技术相比,Servlet具有更好的可移植性、更强大的功能、更节省投资、效率更高、安全性更好、代码结构等特点。
Servlet是使用Java Servlet应用程序设计接口(API)及相关类和方法的Java程序。除Java Servlet API,Servlet还可以使用以扩展和添加API的Java类软件包。Java语言能够实现的功能,Servlet基本上都能实现(除了图形界面外)。Servlet主要用于处理客户端传来的HTTP请求,并返回一个响应。通常所说的Servlet就是指HttpServlet,用于处理HTTP请求,能够处理的请求有doGet()、doPost()、service()等方法。在开发Servlet时,可以直接继承javax.servlet.http. HttpServlet。
Servlet技术功能
Servlet通过创建一个框架来扩展服务器的能力,以提供在Web上进行请求和响应服务。当客户机发送请求至服务器时,服务器可以将请求信息发送给Servlet,并让Servlet建立起服务器返回给客户机的响应。当启动Web服务器或客户机第一次请求服务时,可以自动装入Servlet,之后,Servlet继续运行直到其他客户机发出请求。Servlet的工作流程如图1所示。
servlet 的功能涉及范围很广,主要功能如下:
- 创建并返回一个包含基于客户请求性质的动态内容和完整的HTML页面
- 创建可嵌套到现有HTML页面中的一部分HTML页面(HTML片段).
- 与其他服务器资源(包括数据库和基于java的应用程序)进行通信
- 用多个客户机处理连接,接收多个客户机的输入,并将结果传递到多个客户机,例如,servlet可以是多参与者的游戏服务器
- 当允许在单连接方式下传送数据的情况下,在浏览器上打开服务器至Applet的新连接,并将该连接保持在打开状态,当允许客户机和服务器简单,高效地执行会话的情况下,Applet也可以启动客户浏览器和服务器之间的连接,可以通过定制协议进行通信.
- 讲定制的处理提供给所有服务器的标准程序,例如,servlet可以修改如何认证用户…
Servlet技术特点
Servlet技术带给程序员最大的优势是它可以处理客户端传来的HTTP请求,并返回一个响应。Servlet是一个Java类,Java语言能够实现的功能,Servlet基本上都可以实现(图形界面以外)。总地来说,Servlet技术具有以下特点。
高效
在服务器上仅有一个Java虚拟机在运行, 它的优势在于当多个来自客户端的请求进行访问时,Servlet为每个请求分配一个线程而不是进程。
方便
Servlet提供了大量的实用工具例程, 例如处理很难完成的HTML表单数据、读取和设置HTTP头、处理Cookie和跟踪会话等。
夸平台
Servlet是用Java类编写的,它可以在不同的操作系统平台和不同的应用服务器平台下运行。
功能强大
在Servlet中,许多使用传统CGI程序很难完成的任务都可以利用Servlet技术轻松地完成。例如, Servlet能够直接和Web服务器交互,而普通的CGI程序不能。 Servlet还能够在各个程序之间共享数据,使得数据库连接池之类的功能很容易实现。
灵活性和可扩展性
采用Servlet开发的Web应用程序,由于Java类的继承性、构造函数等特点,使得应用灵活,可随意扩展。
共享数据
Servlet之间可通过共享数据很容易地实现数据库连接池。它能方便地实现管理用户请求,简化Session和获取前一页面信息的操作。而在CGI之间通信则很差。由于每个CGI程序的调用都开始一个新的进程;调用间通信通常要通过文件进行,因而相当缓慢。同一台服务器上的不同CGI程序之间的通信也相当麻烦。
安全
有些CGI版本有明显的安全弱点。即使是使用最新的标准和PERL等语言,系统也没有基本安全框架。而Java定义有完整的安全机制,包括SSL\CA认证、安全政策等规范。
Servlet 开发
创建Servlet
Servlet的创建十分简单,主要有两种创建方法。第一种方法为创建一个普通的Java类,使这个类继承HttpServlet类,再通过手动配置web.xml文件注册Servlet对象。此方法操作比较繁琐,在快速开发中通常不被采纳,而是使用第二种方法进行创建,直接通过IDE集成开发工具进行创建。
使用集成开发工具创建Servlet非常方便,下面以MyEclipse为例介绍下Servlet的创建过程,其它开发工具大同小异。
- 在指定的项目中打开MyEclipse的新建向导,并在“输入过滤器文本”框中输入“servlet” MyEclipse将自动导航到Servlet,如图1所示。
- 选择“Servlet”单击“下一步”按钮,进入到Servlet创建对话框,按提示创建Servlet对象,如图2所示。在这一步要输入Servlet对象的包名及类名,同时MyEclipse还提供了Servlet对象的方法,如doPost()、doGet()等等,可根据实际需要进行选择。
配置Servlet的相关元素
一个Servlet对象的正常运行,需要进行适当的配置,以告知Web容器哪一个请求调用哪一个Servlet对象处理,对Servlet起到一个注册的作用。Servlet的配置包含在web.xml文件中,主要通过以下两部进行设置:
声明Servlet对象
在web.xml文件中,通过元素声明一个Servlet 对象,在此标签下包含两个主要子元素,分别为与.其中元素用于指定Servlet的名称,此名称可以为自定义的名称. 。元素用于指定Servlet对象的完整位置,包含Servlet对象的包名与类名,其声明语句如下:<servlet> <servlet-name>SimpleServlet</servlet-name> <servlet-class>com.lyq.SimpleServlet</servlet-class> </servlet>
在web.xml文件中声明了Servlet对象后,需要映射访问Servlet的URL,此操作使用标签进行配置。标签包含两个子元素,分别为与,其中元素与标签中元素相对应,不可以随意命名。元素用于映射访问URL,其配置方法如下:
<servlet-mapping> <servlet-name>SimpleServlet</servlet-name> <url-pattern>/SimpleServlet</url-pattern> </servlet-mapping>
Servlet的创建及配置
- 创建名称为MyServlet的Servlet对象,它继承HttpServlet类。在此类中重写doGet()方法,用于处理HTTP的get请求,通过PrintWriter对象进行简单输出,其关键代码如下:
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("GBK");
PrintWriter out = response.getWriter();
out.println("<HTML>");
out.println(" <HEAD><TITLE>Servlet实例</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" Servlet实例: ");
out.print(this.getClass());
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
- 在web.xml文件中对MyServlet进行配置,其中的访问的URL的相对路径为“/MyServlet”,其关键代码如下:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.ityang.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
Servlet核心 API
Servlet接口
Servlet是运行在服务器端的Java应用程序,由Servlet容器对其进行管理,当用户对容器发送Http请求时,容器将通知相应的Servlet对象进行处理,完成用户与程序之间的交互。在Servlet编程中,Servlet API提供了标准的接口与类,这些对象对Servlet的操作操作非常重要,它们为Http请求与程序回应提供了丰富的方法。
Servlet的运行需要Servlet容器的支持,Servlet容器通过调用Servlet对象提供了标准的API接口,对请求进行处理。在Servlet开发中,任何一个Servlet对象都要直接或间接的实现javax.servlet.Servlet接口,该接口是Servlet API的核心接口,在此接口中包含5个方法,其功能及作用如表1所示。
方法
说明
public void init(ServletConfig config)
Servlet实例化后,Servlet容器调用此方法来完成初始化工作
public void service(ServletRequest request,ServletResponse response)
此方法用于处理客户端的请求
public void destroy()
当Servlet对象应该从Servlet容器中移除时,容器调用此方法,以便释放资源
public ServletConfig getServletConfig()
此方法用于获取Servlet对象的配置信息,返回ServletConfig对象
public String getServletInfo()
此方法返回有关Servlet的信息,它是纯文本格式的字符串,如作者、版本等
GenericServlet抽象类
在编写一个Servlet对象时,必须实现javax.servlet.Servlet接口,但在Servlet接口中包含5个方法,也就是说创建一个Servlet对象要实现这5个方法,这样操作非常不方便。javax.servlet.GenericServlet类简化了此操作,它对Servlet接口进行了实现。
public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable
GenericServlet类是一个抽象类,它分别实现了Servlet接口与ServletConfig接口,此类对除了service()外的其它方法进行了实现,在创建个Servlet对象时,可以继承GenericServlet类来简化程序中的代码,但需要实现service()方法。
HttpServlet抽象类
HttpServlet类是GenericServlet类的子类。GenericServlet类对javax.servlet.Servlet接口进行了实现,为程序的开发提供了方便。但在实际开发过程中,大多数的应用都是使用Servlet处理HTTP协议的请求,并对请求做出回应,所以通过继承GenericServlet类仍然不是很方便,javax.servlet.http.HttpServlet类对GenericServlet类进行了扩展,为HTTP请求的处理提供了灵活的方法。
public abstract class HttpServlet extends GenericServlet implements Serializable
HttpServlet类仍然是一个抽象类,它对service()方法进行了实现,并针对HTTP1.1中定义的7种请求类型提供了相应的方法,分别为:doGet()方法、doPost()方法、doPut()方法、doDelete()方法、doHead()方法、doTrace()方法、doOptions()方法。在这7个方法中,除了对doTrace()方法与doOptions()方法进行简单实现外,HttpServlet类并没有对其它方法进行实现,需要开发人员在使用过程中,根据实际需要对其进行重写。
HttpServlet类继承GenericServlet类,它对GenericServlet类的扩展,可以很方便的对HTTP请求进行处理及响应,它与GenericServlet类、Servlet接口的关系如图1所示。
HttpServletRequest接口
HttpServletRequest接口位于javax.servlet.http包中,此接口继承了javax.servlet.ServletRequest接口,它是Servlet中的重要接口,在开发过程中非常常用,其常用方法及说明,如表1所示。
表1 HttpServletRequest接口常用方法及说明
方法
说明
public String getContextPath()
返回请求的上下文路径,此路径以“/”开关
public Cookie[] getCookies()
返回请求中发送的所有Cookie对象,返回值为Cookie数组
public String getMethod()
返回请求所使用的HTTP类型,如GET、POST等
public String getQueryString()
返回请求中参数的字符串形式,如请求MyServlet?username=mr,则返回username=mr
public String getRequestURI()
返回主机名到请求参数之间部分的字符串形式
public StringBuffer getRequestURL()
返回请求的URL,此URL中不包含请求的参数,注意此方法返回的数据类型为StringBuffer
public String getServletPath()
返回请求URI中的Servlet路径的字符串,不包含请求中的参数信息。
public HttpSession getSession()
返回与请求关联的HttpSession对象
- HttpServletRequest接口的使用
创建名称为MyServlet类,它是一个Servlet,在此类中通过PrintWriter对象,向页面中输出HttpServletRequest对象中方法所获取的值,其关键代码如下:
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("GBK");
PrintWriter out = response.getWriter();
out.print("<p>上下文路径:" + request.getServletPath() + "</p>");
out.print("<p>HTTP请求类型:" + request.getMethod() + "</p>");
out.print("<p>请求参数:" + request.getQueryString() + "</p>");
out.print("<p>请求URI:" + request.getRequestURI() + "</p>");
out.print("<p>请求URL:" + request.getRequestURL().toString() + "</p>");
out.print("<p>请求Servlet路径:" + request.getServletPath() + "</p>");
out.flush();
out.close();
}
}
- 在web.xml文件中,对MyServlet类进行配置,其关键代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<description>This is the description of my J2EE component</ description>
<display-name>This is the display name of my J2EE component</display- name>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.lh.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
/servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
注意
在浏览器地址栏中输入“http://localhost:8080/项目名/ MyServlet?action=test”,进行测试
HttpServletResponse接口
- HttpServletResponse接口位于javax.servlet.http包中,它继承了javax.servlet.ServletResponse接口,此接口仍然非常重要,其常用方法与说明如表1所示。
表1 HttpServletResponse接口常用方法及说明
方法
说明
public void addCookie(Cookie cookie)
向客户端写入Cookie信息
public void sendError(int sc)
发送一个错误状态码为sc的错误响应到客户端
public void sendError(int sc, String msg)
发送一个包含错误状态码及错误信息的响应到客户端,参数sc为错误状态码,参数msg为错误信息
public void sendRedirect(String location)
使用客户端重定向到新的URL,参数location为新的地址
- 在程序开发过程中,经常会遇到异常的产生,本实例使用HttpServletResponse向客户端发送错误信息。
创建一个名称为MyServlet的Servlet对象,在doGet()方法中模拟一个开过过程中的异常,并将其通过thorw关键字抛出,其关键代码如下:
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//创建一个异常
throw new Exception("数据库连接失败");
} catch (Exception e) {
response.sendError(500, e.getMessage()); //向客户端响应一个异常
}
}
}
- 此类对程序中的异常通过catch进行捕获,使用HttpServletResponse对象的sendError()方法,向客户发错误信息,实例运行效果如图1所示。
ServletConfig接口
ServletConfig接口位于javax.servlet包中,该接口用于封装Servlet的初始化参数信息,在Servlet初始化期间被传递,每一个Servlet都有且只有一个ServletConfig对象,此接口中定义了四个方法,方法的声明及说明如表1所示。
表1 ServletConfig接口中方法及说明
方法
说明
public String getInitParameter(String name)
此方法返回String类型名称为name的初始化参数值
public Enumeration getInitParameterNames()
获取所有初始化参数名的枚举集合
public ServletContext getServletContext()
用于获取Servlet上下文对象
public String getServletName()
返回Servlet对象的实例名
理解Servlet的生命周期
Servlet部署在容器里,它的生命周期由Servlet容器进行控制。Servlet的生命周期可以分成三个阶段:初始化阶段、运行时阶段和销毁阶段。
- 初始化阶段
Servlet初始化阶段包括以下4个步骤:
(1)当Web客户请求Servlet服务或当Web服务启动时,容器环境加载一个Servlet类。
(2)Servlet容器创建ServletConfig对象,用于配置Servlet的初始化信息。
(3)Servlet容器创建一个Servlet对象。
(4)Servlet容器调用Servlet对象的初始化方法init()进行初始化。并且需要给init()方法传入一个ServletConfig对象,ServletConfig对象包含了初始化参数和容器环境的信息,并负责向Servlet传递数据,如果传递失败,则会发生ServletException异常,Servlet将不能正常工作。
- 运行时阶段
在这个阶段,Servlet可以随时响应客户端的请求。当容器环境接收到要求访问特定Servlet的客户请求时,容器会建立针对这个请求的ServletRequest对象和ServletResponse对象,然后调用Servlet对象的service()方法。service()方法接受ServletRequest对象和 ServletResponse对象来处理请求和发送响应。
当Servlet容器已经把Servlet生成的响应结果发送给了客户,容器就会ServletRequest对象和ServletResponse对象。
- 销毁阶段
当Web应用被终止时,Servlet容器会调用Web应用中所有Servlet对象的destroy()方法,然后再销毁这些Servlet对象。通过destroy()方法,可以释放Servlet所占用的资源(比如内存、文件处理和线程)。
Servlet生命周期的各个阶段,如图1所示。
Servlet过滤器
过滤器概述
过滤器是Web程序中的可重用组件,它在Servlet2.3规范中被引入,其应用十分广泛,为Java Web程序的开始带来了更加强大的功能。
Servlet过滤器是客户端与目标资源间的中间层组件,用于拦截客户端的请求与响应信息,如图1所示。当Web容器接收到一个客户端请求时,Web容器判断此请求是否与过滤器对象相关联,如果相关联,容器将这一请求交给过滤器进行处理。在处理过程之中,过滤器可以对请求进行对象进行操作,如更改请求中的信息数据,在过滤器处理完成之后,再将这一请求交给其它业务进行处理。当所有业务处理完成,需要对客户端进行响应时,容器又将响应交给过滤器进行处理,过滤器处理响应完成将响应发送到客户端。
图1 过滤器的应用
在Web程序的应用过程中,可以放置多个过滤器,如字符编码过滤器、身份验证过滤器等等,Web容器对多个过滤器的处理方式如图2所示。
图2 多过滤器的应用
在多个过滤器的处理方式中,容器首先将客户端请求交给第一个过滤器处理,处理完成之后交给下一过滤器处理,以此类推直至到最后一个过滤器对象。当需要对客户端回应时,如图2所示,将按照相反的方向对回应进行处理,直到交给第一个过滤器,最后发送到客户端回应。
过滤器API
过滤器与Servlet非常相似,它的使用通过三个核心接口进行操作,分别为:Filter接口、FilterChain接口与FilterConfig接口。
- Filter接口
Filter接口位于javax.servlet包中,与Servlet接口相似,当定义一个过滤器对象需要实现此接口,在Filter接口中包含三个方法,其方法声明及作用如表1所示。
表1 Filter接口中方法及说明
方法
说明
public void init(FilterConfig filterConfig)
过滤器的初始化方法,容器调用此方法完成过滤的初始化,对于每一个Filter实例,此方法只被调用一次
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
此方法与Servlet的service()方法相类似,当请求及响应交给过滤器时,过滤器调用此方法进行过滤处理
public void destroy()
在过滤器生命周期结束时调用此方法。此方法可用于释放过滤器所占用的资源
- FilterChain接口
FilterChain接口位于javax.servlet包中,此接口由容器进行实现,在FilterChain接口只包含一个方法,其方法声明如下:
void doFilter(ServletRequest request,ServletResponse response)throws IOException,ServletException
此方法主要用于将过滤器处理的请求或响应,传递给下一个过滤器对象。在多个过滤器的Web应用中,可以通过此方法进行传递。
- FilterConfig接口
FilterConfig接口位于javax.servlet包中,此接口由容器进行实现,用于获取过滤器初始化期间的参数信息,其方法声明及说明如表2所示。
表2 FilterConfig接口中方法及说明
方法
说明
public String getFilterName()
返回过滤器的名称
public String getInitParameter(String name)
返回初始化名称为name的参数值
public Enumeration getInitParameterNames()
返回所有初始化参数名的枚举集合
public ServletContext getServletContext()
返回Servlet的上下文对象
了解了过滤器的这三个核心接口,就可以通过实现Filter接口来创建一个过滤器对象,其代码结构如下:
public class MyFilter implements Filter {
// 初始化方法
public void init(FilterConfig arg0) throws ServletException {
}
// 过滤处理方法
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
throws IOException, ServletException {
// 传递给下一过滤器
chain.doFilter(request, response);
}
// 销毁方法
public void destroy() {
}
}
配置过滤器
在创建一个过滤器对象之后,需要对其进行配置才可以使用。过滤器的配置方法与Servlet的配置方法相类似,都通过web.xml文件进行配置,其配置方法由以下两部进行实现:
(1)声明过滤器对象
在web.xml文件中,通过标签声明一个过滤器对象,在此标签下包含三个常用子元素,分别为、和。其中元素用于指定过滤器的名称,此名称可以为自定义的名称。元素用于指定过滤器对象的完整位置,包含过滤器对象的包名与类名。元素用于设置过滤器的初始化参数,其配置方法如下:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.lyq.util.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
元素包含两个常用的子元素,分别为与,其中元素用于声明初始化参数的名称,元素用于指定初始化参数的值。
(2)映射过滤器
在web.xml文件中声明了过滤器对象后,需要映射访问过滤器的过滤的对象,此操作使用标签进行配置。在标签中主要需要配置过滤器的名称、过滤器关联的URL样式、过滤器对应的请求方式等,其配置方法如下:
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
1. <filter-name>元素:用于指定过滤器的名称,此名称与<filter>标签中<filter-name>相对应。
2. <url-pattern>元素:用于指定过滤器关联的URL样式,设置为“/*”为关联所有URL。
3. <dispatcher>元素:用于指定过滤器对应的请求方式,其可选值及使用说明如表1所示。
表1 <dispatcher>的可选值及说明
可选值
说明
REQUEST
当客户端直接请求时,则通过过滤器进行处理
INCLUDE
当客户端通过RequestDispatcher对象的include()方法请求时,则通过过滤器进行处理
FORWARD
当客户端通过RequestDispatcher对象的forward()方法请求时,则通过过滤器进行处理
ERROR
当声明式异常产生时,则通过过滤器进行处理
#### 编写字符编码过滤器 ####
在Java Web项目的开发中,过滤器的使用十分广泛,在大小项目之中基本都会使用。其中比较典型的应用就是字符编码过滤器。由于Java程序可以多种平台下运行,其内部使用Unicode字符集来表示字符,所以处理中文数据会产生乱码的情况,需要对其进行编码转换才可以正常显示。
- 字符编码过滤器。
创建字符编码过滤器类CharacterEncodingFilter,此类实现Filter接口,并对它的三个方法进行了实现,其关键代码如下:
package com.filter.servlet;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CharacterEncodingFilter implements Filter{
//字符编码(初始化参数)
protected String encoding=null;
//FilterConfig 对象
protected FilterConfig filterConfig=null;
/* (非 Javadoc)
* @see javax.servlet.Filter#destroy()
* 销毁方法
*/
@Override
public void destroy() {
// TODO 自动生成的方法存根
//释放资源
this.encoding=null;
this.filterConfig=null;
}
/* (非 Javadoc) 过滤器处理方法
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 判断字符编码是否有效
if (encoding!=null) {
//设置request字符编码
request.setCharacterEncoding(encoding);
//设置response 字符编码
response.setContentType("text/html;charset="+encoding);
}
//传递给下一过滤器
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//对filterConfig 赋值
this.filterConfig=filterConfig;
//对初始化参数赋值
this.encoding=filterConfig.getInitParameter("encoding");
}
}
- CharacterEncodingFilter类的init()方法用于读取过滤器的初始化参数,这个参数encoding为实例中所用到的字符编码。在doFilter()方法中,分别将request对象及response对象中的编码格式设置为读取到的编码格式。最后在destroy()方法将其属性设置为null,将被Java垃圾回收器回收。
在web.xml文件中,对过滤器进行配置,其关键代码如下:
<!-- 声明字符编码过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.lyq.util.CharacterEncodingFilter</filter-class>
<!-- 设置初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<!-- 映射字符编码过滤器 -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 与所有请求关联 -->
<url-pattern>/*</url-pattern>
<!-- 设置过滤器对应的请求方式 -->
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
- 在web.xml配置文件中,需要对过滤器进行声明及映射,其中声明过程通过指定了初始化参数的字符编码为GBK。
通过请求对过滤器进行验证。实例中使用表单向Servlet发送中文信息进行测试,其中表单信息放置在index.jsp页面中,其关键代码如下:
<form action="MyServlet" method="post">
<p>
请输入你的中文名字:
<input type="text" name="name">
<input type="submit" value="提 交">
</p>
</form>
- 这一请求由Servlet对象MyServlet类进行处理,此类使用doPost()方法接收表单的请求,并将表单中的name属性输出在页面之中,其关键代码如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
// 获取表单参数
String name = request.getParameter("name");
if(name != null && !name.isEmpty()){
out.print("你好 " + name);
out.print(",<br>欢迎来到我的主页。");
}else{
out.print("请输入你的中文名字!");
}
out.print("<br><a href=index.jsp>返回</a>");
out.flush();
out.close();
}