6.Servlet、Filter过滤器以及监听器
Servlet 是运行在Web服务器端的Java程序,它使用Java语言编写,与Java程序的区别是Servlet对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持,在Java Web应用方面,Servlet的应用占有十分重要的地位,它在Web请求的处理功能也非常强大。
Servlet与JSP的区别:
1.角色不同:JSP页面可以存在HTML代码和Java代码并存的情况,而Servlet需要承担客户请求和业务处
理的中间角色,只有调用固定的方法才能将动态内容输出为静态的HTML,所以JSP更具有显示层角色;
2.编译时间不同:Servlet需要在Java编译器编译后才能运行,如果它在编写完成或修改后没有重新编译
就不能运行在Web容器中。而JSP由JSP Container对其进行管理,JSP Container对JSP进行自动编译,不需
要手动执行编译就可执行;
3.速度不同:因为Java Container在每次执行不同内容的动态JSP页面时都要对JSP自编译,而Servlet
在编译之后可以直接获取和输出动态内容,所以JSP的效率比Servlet低。
Servlet API常用的接口和类:
1.Servlet接口
Servlet的运行需要Servlet容器的支持,Servlet容器通过调用Servlet对象提供了标准的API接口对请求进行处理。
public void init(ServletConfig config) 初始化工作
public void service(ServletRequest request, ServletResponse reponse) 处理客户端请求
public void destroy() 当Servlet对象从Servlet容器移除时,释放资源
public ServletConfig getServletConfig() 用于获取Servlet对象的配置信息,返回ServletConfig对象
public String getServletInfo() 返回有关Servlet的信息,如作者版本等
2.ServletConfig接口
ServletConfig接口位于javax.servlet包中,它封装了Servlet的配置信息,在Servlet初始化期间被传递。每一个Servlet对象都有且只有一个ServletConfig对象。
public String getInitParameter(String name) 返回名称为name的初始化参数的值
public Enumeration getInitParameterNames() 获取所有初始化参数名的枚举集合
public ServletContext getServletContext() 获取Servlet上下文对象
public String getServletName() 返回Servlet对象的实例名
3.HttpServletRequest接口
该接口位于javax.servlet.http包中,继承了javax.servlet.ServletRequest接口。
public String getContextPath() 返回请求的上下文路径,以“/”开头
public Cookie[] getCookies() 返回请求中发送的所有Cookie对象
public String getMethod() 返回请求所使用的HTTP类型,如“get, post”
...
4.HttpServletResponse接口
public void addCookie(Cookie cookie) 向客户端写入Cookie
...
5.GenericServlet类
抽象类,分别实现了Servlet和ServletConfig类的接口。但需要实现service()。
6.HttpServlet类
抽象类,继承了GenericServlet类,实现了service()。最为方便。
Servlet创建:
在Eclipse中新建一个Web项目,在创建项目过程中点击下一步勾选Generate web.xml
之后在src目录下创建包,然后创建Servlet类
创建Servlet有两种方法:
1.创建一个普通的java类,使其继承HttpServlet类,然后再手动配置web.xml文件(位置见上图)注册Servlet对象。
Servlet配置:声明Servlet对象:
<servlet> <servlet-name>MyServlet</servlet-name> //指定Servlet名称,可自定义 <servlet-class>ServletSrc.AddServlet</servlet-class> //指定Servlet对象的完整位置,包含Servlet对象的包名和类名 </servlet>
映射Servlet:
<servlet-mapping> <servlet-name>MyServlet</servlet-name> //与上面的Servlet name对应,不可随意命名 <url-pattern>/MyServlet</url-pattern> //用于映射访问URL(反映在网页地址栏中) </servlet-mapping>
2.直接在Eclipse中右击包创建Servlet类
它会在类声明之前自动添加注释:@WebServlet(“这里面有众多属性可设置”) 使用该注释就无需对web.xml修改。同样的还有@WebFilter()、@WebListener、@WebInitParam
Servlet代码结构:
通常Servlet是指HttpServlet对象,在声明一个对象为Servlet时,需要继承HttpServlet类。HttpServlet类是Servlet接口的一个实现类,继承该类后,可重写HttpServlet类中的方法对HTTP请求进行处理。
Servlet过滤器
Servlet过滤器具有拦截客户端请求的功能,它可以改变请求中的内容来满足实际需求。如果一个不够用还可以设置多个形成一个过滤链。
Servlet过滤器对象放在 java.servlet包中,名称为Filter,除此以外还有FilterConfig对象和FilterChain对象。
Filter接口:
每个过滤器对象都要实现该接口。
public void init(FilterConfig filterConfig) throws ServletException 初始化方法
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOEException,ServletException 对请求进行过滤操作
public void destroy() 销毁方法,释放资源
FilterConfig接口:
由Servlet容器实现,主要用于获取过滤器的配置信息。
public String getFilterName() 用于获取过滤器的名字
public ServletContext getServletContext() 获取Servlet上下文
public String getInitParameter(String name) 获取过滤器的初始化参数值
public Enumeration getInitParameterNames() 获取过滤器的所有初始化参数
FilterChain接口:
也有Servlet容器实现。
public void doFilter(ServletRequest request, ServletResponse response) throws IOException,ServletException
该方法用于将过滤后的请求传递给下一个过滤器,如果此过滤器是最后一个,则将请求传递给目标资源
Filter创建
和Servlet一样,如果手动配置需要在web.xml中配置过滤器:
<filter> //规则和Servlet一致 <filter-name>MyFilter</filter-name> <filter-class>FilterSrc.CharactorFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/MyFilter</url-pattern> </filter-mapping>
也可以使用自动生成的@WebFilter().
Filter实例:
1.过滤敏感字符
WordFilter.java
package com; 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; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; @WebFilter(filterName="/CharactorFilter",value = {"/*"},initParams= {@WebInitParam(name="encoding",value="UTF-8")} ) public class WordFilter implements Filter { // 非法字符数组 private String words[]; // 字符编码 private String encoding; // 实现Filter接口init()方法 @Override public void init(FilterConfig filterConfig) throws ServletException { // 获取字符编码 encoding = filterConfig.getInitParameter("encoding"); // 初始化非法字符数组 words = new String[]{"糟糕","混蛋"}; } // 实现Filter接口doFilter()方法 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 判断字符编码是否有效 if (encoding != null) { // 设置request字符编码 request.setCharacterEncoding(encoding); // 将request转换为重写后的Request对象 request = new Request((HttpServletRequest) request); // 设置response字符编码 response.setContentType("text/html; charset="+encoding); } chain.doFilter(request, response); } // 实现Filter接口destroy()方法 @Override public void destroy() { this.words = null; this.encoding = null; } /** * 内部类重写HttpServletRequestWrapper*/ class Request extends HttpServletRequestWrapper{ // 构造方法 public Request(HttpServletRequest request) { super(request); } // 重写getParameter()方法 @Override public String getParameter(String name) { // 返回过滤后的参数值 return filter(super.getRequest().getParameter(name)); } // 重写getParameterValues()方法 @Override public String[] getParameterValues(String name) { // 获取所有参数值 String[] values = super.getRequest().getParameterValues(name); // 通过循环对所有参数值进行过滤 for (int i = 0; i < values.length; i++) { values[i] = filter(values[i]); } // 返回过滤后的参数值 return values; } } /** * 过滤非法字符 * @param param 参数值 * @return 过滤后的参数值 */ public String filter(String param){ try { // 判断非法字符是否被初始化 if(words != null && words.length > 0){ // 循环替换非法字符 for (int i = 0; i < words.length; i++) { // 判断是否包含非法字符 if(param.indexOf(words[i]) != -1){ // 将非法字符替换为"****" param = param.replaceAll(words[i], "****"); } } } } catch (Exception e) { e.printStackTrace(); } return param; } }
AddServlet.java
package com; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class AddServlet */ @WebServlet("/AddServlet") public class AddServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public AddServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub PrintWriter out = response.getWriter(); String string = request.getParameter("string"); out.print("输入成功123<br>"+string); out.flush(); out.close(); doGet(request, response); } }
index.html
<!DOCTYPE html> <html> <head> <meta charset="GB2312"> <title>非法字符过滤</title> </head> <body> <h2>非法字符过滤</h2> <form action="AddServlet" method="post"> <input type="text" name="string"> <input type="submit" value="提交"> </form> </body> </html>
效果:
Servlet监听器
监听器的作用是监听web容器的有效时间,利用Listener接口监听在容器中的某个执行程序,并且根据其应用程序的需求做出适当的响应。
1.Servlet上下文监听
1.ServletContextListener接口
2.ServletAttributeListener接口
2.HTTP会话监听
1.HttpSessionListener接口
2.HttpSessionActivactionListener接口
3.HttpBindingListener接口
4.HttpSessionAttributeListener接口
3.Servlet请求监听
1.ServletRequestListener接口
2.ServletRequestAttributeListener接口
文件上传
人生不如意的时候,是上帝给的长假,这个时候应该好好享受假期。
突然有一天假期结束,时来运转,人生才是真正开始了。
突然有一天假期结束,时来运转,人生才是真正开始了。