Servlet

1. Web容器为每个请求分配一个线程

2. Web容器默认采用单Servlet实例处理请求.

3. Servlet3.0中可以使用注解定义Servlet匹配的URL, web.xml中的配置会覆盖Servlet中的标注配置

1 @WebServlet("/index")
2 public class IndexServlet extends HttpServlet { }

更高级的配置

1 @WebServlet(name = "index",                        //默认为Servlet类的完整名称
2     urlPatterns = {"/index", "/index.view"},       //可以匹配多个URL
3     initParams = {                                 //配置多个初始化参数
4         @WebInitParam(name="username", value="admin"),
5         @WebInitParam(name="password", value="admin")
6     },
7     loadOnStartup = 1                  //默认为-1, 请求该Servlet时才加载
8 )
9 public class IndexServlet extends HttpServlet { }

且需将web.xml文件头设置为

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">

</web-app>

4. @WebServlet 属性列表

name String 指定Servlet的name属性, 等价于<servlet-name>, 如果没有显示指定, 则为类的全限定名
value String[] 该属性等价于urlPartterns属性, 两个属性不能同时使用
urlPatterns String[] 指定一组Servlet的URL匹配模式, 等价于<url-pattern>
loadOnStartup int 指定Servlet加载顺序, 等价于<load-on-startup>. 大于等于0时, 表示应用启动时就加载; 小于0或未指定时表示请求时才加载; 正数值越小, 优先级越高
initParams WebInitParam[]  指定一组Servlet初始化参数, 等价于<init-param>
asyncSupported  boolean 声明Servlet是否支持异步操作模式, 等价于<async-supported>
description String 该Servlet的描述信息, 等价于<description>
displayName String 该Servlet的显示名, 通常配合工具使用, 等价于<display-name>

5. WEB-INF中的文件和目录对外界是封闭的, 如果想访问其中的内容, 需要通过JSP或Servlet的请求转发(Forward)

6. 命令行打war包, 在项目目录下运行  jar cvf  ../HelloWorld.war *

7. requestURI = contextPath + servletPath + pathInfo   

分别对应HttpServletRequest的方法 req.getRequestURI(); req.getContextPath(); req.getServletPath(); req.getPathInfo();

8. 类的查找路径:  /WEB-INF/classes  -->  /WEB-INF/lib  -->  容器实现本身存放类或Jar的目录(如:Tomcat安装目录下的lib目录)

9. Servlet3.0中, JAR文件可以作为Web应用程序的模块(web-fragment.xml放在jar文件的META-INF目录). 可以在Eclipse中新建 Web Fragment Project 

10. 在获取任何HttpServletRequest请求参数(req.getParameter("xxx"))前, 调用 req.setCharacterEncoding("UTF-8"); 设置字符集, 可以避免乱码. 只对请求body中的字符有效, 所以如果请求方法为Get, 则需如此转换 String name = new String(req.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");

11. 通过HttpServletRequest读取请求body

1 BufferedReader reader = req.getReader();
2 String requestBody = "";
3 String input = null;
4 while ((input = reader.readLine()) != null) {
5     requestBody += input;
6 }

12. Servlet3.0 中使用 req.getPart("xxx"); 处理上传文件, 但Servlet要加 @MultipartConfig 注解

13. 调用RequestDispatcher的 forward() 方法前不能有任何响应确认(向客户端输出); 使用 include() 时, 被包含Servlet中任何对请求头的设置都会被忽略.

14. 设置响应字符编码: resp.setLocale(Locale.SIMPLIFIED_CHINESE)resp.setCharacterEncoding()resp.setContentType(), 后两种会覆盖第一种.

15. 注销session: req.getSession().invalidate();

16. HttpSession并非线程安全 

17. Servlet3.0中可以通过 getServletContext().getSessionCookieConfig() 获取SessionCookieConfig对象, 从而对保存SessionId的cookie进行相关操作, 如设置cookie的名字, 存活期限等, 但操作SessionCookieConfig必须在ServletContext初始化之前, 所以可以 1) 在web.xml中设定; 2) 实现ServletContextListener

18. Web容器启动后, 会读取Servlet设置信息, 将Servlet加载并实例化, 并为每个Servlet设置信息产生一个ServletConfig对象, 然后调用Servlet接口的init()方法, 并将产生的ServletConfig对象传入. 这个过程只会在创建Servlet实例后发生一次, 以后每次请求到来, 会调用Servlet实例的service()方法.

19. ServletContextListener接口, 在Web应用程序初始化或即将结束销毁前, 会调用该接口实现类的 contextInitialized() contextDestoryed(), 并传入 ServletContextEvent, 其中封装了ServletContext

Servlet3.0中可以使用 @WebListener 注解

1 @WebListener
2 public class MyContextListener implements ServletContextListener {  }

否则需要在web.xml中声明

<listener>
      <listener-class>tonny.study.listener.MyContextListener</listener-class>
</listener>
<servlet>...<servlet/>

20. ServletContextAttributeListener接口, 当ServletContext中的属性被设置(attributeAdded()), 移除(attributeRemoved()), 替换(attributeReplaced())时获取通知, 并传入ServletCAttributeEvent对象. 需要加标注 @WebListener 或在 web.xml 中声明

21. HttpSessionListener接口, 当HttpSession对象创建(sessionCreated())或结束(sessionDestroyed())时获取通知, 并传入HttpSession对象. 需要加标注 @WebListener 或在 web.xml 中声明

22. HttpSessionAttributeListener接口, 当HttpSession中加入(attributeAdded()), 移除(attributeRemoved()), 替换(attributeReplaced())属性时获取通知, 并传入 HttpSessionBindingEvent 对象. 需要加标注 @WebListener 或在 web.xml 中声明

23. HttpSessionBindingListener接口, 如果某个对象实现了该接口, 则当该对象被加入(valueBound()), 移除(valueUnbound())HttpSession时收到通知, 并传入 HttpSessionBindingEvent 对象.

24. HttpSessionActivationListener接口, 在分布式环境中用到, 此时应用程序的对象可能分散在多个JVM中.

25. ServletRequestListener接口, 当HttpServletRequest对象生成(requestInitialized())或销毁(requestDestroyed())时获取通知, 并传入ServletRequestEvent对象. 需要加标注 @WebListener 或在 web.xml 中声明

26. ServletRequestAttributeListener接口, 当HttpServletRequest中加入(attributeAdded()), 移除(attributeRemoved())或替换(attributeReplaced())属性时获取通知, 并传入ServletRequestAttributeListener对象. 需要加标注 @WebListener 或在 web.xml 中声明

27.  实现Filter接口实现过滤器, 使用 @WebFilter 标注或在 web.xml 中声明.

1 //@WebFilter("/LoginFilter")
2 @WebFilter(
3         filterName = "loginFilter",
4         urlPatterns = {"/admin", "/user"},
5         servletNames = {"IndexServlet", "AdminServlet"}
6 )
7 public class LoginFilter implements Filter {  }
<filter>
      <filter-name>loginFilter</filter-name>
      <filter-class>tonny.study.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>loginFilter</filter-name>
  <url-pattern>/admin</url-pattern>
  <servlet-name>index</servlet-name>
</filter-mapping>
  
<servlet> ... </servlet>

@WebFilter的常用属性

filterName String 指定过滤器的 name 属性, 等价于 <filter-name>
value String[] 该属性等价于 urlPatterns 属性。但是两者不应该同时使用
urlPartterns String[] 指定一组过滤器的 URL 匹配模式。等价于 <url-pattern> 标签
servletNames String[] 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中 <servlet-name> 的取值
dispatcherType DispatcherType 指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST, 默认是Request, 即浏览器发出请求时触发过滤器
initParams WebInitParam[]  指定一组过滤器初始化参数,等价于 <init-param> 标签
asyncSupported  boolean 声明过滤器是否支持异步操作模式,等价于 <async-supported> 标签
description String 该过滤器的描述信息,等价于 <description> 标
displayName String 该过滤器的显示名,通常配合工具使用,等价于 <display-name> 标签

28. 如果调用了 FilterChain 的doFilter()方法, 就会运行下一个过滤器, 如果没有则调用目标Servlet的service方法, 从而实现对service() 方法的前置处理. 在陆续调用完Filter实例的doFilter()和Servlet的Service()(如果请求没被拦截的话)之后, 流程会议堆栈顺序返回, 从而实现对 service() 方法的后置处理.z

1 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
2     //service()前置处理, 比如记录此时的时间,然后在后置处理中计算方法的耗时
3     chain.doFilter(request, response);
4     //service()后置处理
5 }

 29. 使用HttpServletRequestWrapper, HttpServletResponseWrapper配合Filter.

 1 /**
 2  * 编码过滤器
 3  * HttpServletRequestWrapper实现了HttpServletRequest接口, 继承它以后, 只需覆盖想重新编写的方法即可.
 4  * 在Filter中将原始HttpservletRequest对象转成自定义对象, 并传递给doFilter方法, 从而实现自定义逻辑
 5  * @author kaitang.yi
 6  * @date 2013-7-31 下午5:45:02
 7  */
 8 public class EncodingWrapper extends HttpServletRequestWrapper {
 9     private String encoding;
10     
11     public EncodingWrapper(HttpServletRequest request, String encoding) {
12         super(request);        //必须调用父类构造器
13         this.encoding = encoding;
14     }
15     
16     @Override
17     public String getParameter(String name) {
18         String value = getRequest().getParameter(name);
19         
20         if(value != null) {
21             try {
22                 byte[] bytes = value.getBytes("ISO-8859-1");
23                 value = new String(bytes, encoding);    //按指定编码重新构造字符串
24             } catch (UnsupportedEncodingException e) {
25                 e.printStackTrace();
26             }
27         }
28         
29         return value;
30     }
31 }
32 
33 
34 @WebFilter(
35         urlPatterns = {"/*"},
36         initParams = {
37                 @WebInitParam(name = "encoding", value = "UTF-8")
38         }
39 )
40 public class EncodingFilter implements Filter {
41     private String encoding;
42     
43     public void init(FilterConfig fConfig) throws ServletException {
44         encoding = fConfig.getInitParameter("encoding");
45     }
46     
47     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
48         HttpServletRequest req = (HttpServletRequest) request;
49         
50         if ("GET".equals(req.getMethod())) {
51             req = new EncodingWrapper(req, encoding);
52         } else {
53             req.setCharacterEncoding(encoding);        //只对请求body中的字符有效, 所以有了上面的判断
54         }
55         
56         chain.doFilter(request, response);
57     }
58     
59     public void destroy() {
60     }
61 }

 

 

参考:

《JSP&Servlet学习笔记(第二版)》

Servlet3.0新特性详解

 

posted @ 2013-07-31 14:37  堂哥  阅读(479)  评论(0编辑  收藏  举报