一、Servlet的请求流程
web项目中的web.xml文件配置为:
1 2 3 4 5 6 7 8 9 10 11
| <servlet> <servlet-name>Hello</servlet-name> <servlet-class>hello.HelloServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
|
1、第一次在浏览器地址栏输入http://localhost:80/test/hello 后回车(第一次请求)
2、此时servlet会解析这个请求信息,首先前面的localhost:80一般是域名信息,一般会交给DNS解析成ip,80是http协议的默认端口.这里主要讨论后面的一部分,test/hello
3、服务器会tomcat目录里的conf目录下寻找service.xml文件,在所有Context元素中寻找path内容为这里的test的,可以找到这个元素中属性docBase的内容,根据docBase中的路径找到这个web项目的根路径
4、在项目的根路径下寻找web.xml文件,也就是上面的文件,在这个文件中寻找url-patternd内容为hello的元素,如果没有就会报404错误,说明资源不存在。如果有,找到和他在一个元素中的servlet-name,根据这个名字它会去寻找上面servlet元素中的和它同名元素,最终找到servlet-class中的类的全限定名称。
5、利用反射去调用Serlvet类中的构造器从而创建对象(显然构造器必须是public的)。
Servlet ser = ClassforName(“hello.HelloServlet”);
6、调用init方法,ser.init(ServletConfig config);
7、调用service方法 ser.service(…);
8、对浏览器做出响应,以html等形式
9、正常终止服务器,会执行destroy() 但是如果非正常终止并不会执行此方法。
如果是非第一次请求,不会在第5步创建对象了,而是直接从servlet的实例缓冲池中直接获取对象。接着执行后续操作。
注意:servlet的创建,初始化,运行和销毁等操作都是有服务器来负责调用的。
javax.servlet.Servlet接口中有四个方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public void init(ServletConfig config) throws ServletException { }
public ServletConfig getServletConfig() { return null; }
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { }
public String getServletInfo() { return null; }
public void destroy() { }
|
二、Servlet的初始化参数
在web.xml文件中的Servlet元素下可以添加初始化参数:
1 2 3 4 5 6 7 8 9 10
| <servlet> <servlet-name>Hello</servlet-name> <servlet-class>hello.HelloServlet</servlet-class> <init-param> <param-name>name</param-name> <param-value>Willing</param-value> </init-param> </servlet>
|
获取初始化参数就要用到ServletConfig接口中的方法
1 2
| String name = config.getInitParameter("name"); Enumeration<String> en = config.getInitParameterNames();
|
因为它们并不是static方法,所有要用ServletConfig的对象去调用,实际上对象服务器已经帮我们创建好了,在init方法init(ServletConfig config)的参数中,我们只需拿来用。方便起见可定义为成员变量.
1 2 3 4 5
| ServletConfig config; @Override public void init(ServletConfig config) throws ServletException { this.config = config; }
|
三、Servlet的继承体系
每次写一个servlet都得实现javax.servlet.Servlet肯定很痛苦。所有就有专门的来已经实现好了,自己只需要继承就行了。servlet的继承体系
我们只要继承HttpServlet,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L;
public void init() throws ServletException { }
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
|
四、HttpSevletRequst的常用方法
HttpServletRequst是ServletRequest的子接口,封装了处理http协议请求的方法
1 2 3 4 5 6 7
| String getMethod(); String getRequestURI(); StringBuffer getRequestURL(); String getContextPath(); String getHeader(String name) String getParameter(String name); String getParameterValues(String name);
|
请求乱码处理
请求默认是ISO-8859-1,不支持中文
- 方式一:解决中文乱码
- 1.按照ISO-8859-1把乱码恢复成二进制形式byte[] data = username.getBytes(“ISO-8859-1”);
- 2.对二进制形式重新编码为UTF-8,username = new String(data,”UTF-8”);
- 方式二(推荐):可以调用req.setCharacterEncoding(“UTF-8”);//适用于POST方式
- 方式三:修改service.xml配置文件中修改端口的的元素,修改GET方式的默认编码: URIcoding = “UTF-8”;//适用于GET方式
五、HttpServletResponse的常用方法
HttpServletResponse是ServletResponse的子接口,封装了处理http协议请求的方法
1 2 3
| ServletOutputStream getOutputStream(); PrintWriter getWriter() void addCookie(Cookie cookie)
|
注意:这里字节输出流不能和字符输出流共存。
响应乱码处理
1 2 3 4 5 6 7 8 9
|
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
|
1 2 3 4 5 6 7 8 9 10 11 12
|
PrintWriter p = resp.getWriter(); p.println("你好"); p.print("Hello");
|
六、注解配置Servlet
JavaEE6(Servlet3) 可以用注解配置,代替了web.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@WebServlet(value = {"/test","/hello"} ,initParams = { @WebInitParam( name = "encoding" ,value = "UTF-8"), @WebInitParam( name = "name" , value = "Willing") } ) public class AnnServlet extends HttpServlet {
private static final long serialVersionUID = 1L; @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String encoding = getInitParameter("encoding"); String name = getInitParameter("name"); System.out.println(encoding+","+name); } }
|