Servlet 学习(二)
Servlet处理请求参数
HttpServletRequest对象提供了获取get、post请求参数的方法 getParamter
- Tomcat收到浏览器请求时候
- 先解析请求行和请求头,然后将这些信息存储到request对象中。
- 执行Servlet可以收到request
- 对于Post请求
- post请求参数在"请求Body"中传输到服务器
- request对象在第一次调用getParamter时候解析请求Body中的参数
- request会按照ISO8859-1编码解析post请求参数。
- 对于get请求
- get请求参数在“请求行”中传递到服务器
- tomcat默认按照ISO8859-1编码解析请求行和请求头,并且存储到request对象
- getParamter方法执行时候不进行编码解析。
获取post请求案例:
-
编写客户端页面 login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页</title>
</head>
<body>
<h1>登录</h1>
<p>利用Servlet处理请求参数, 表单大多使用post请求</p>
<form action="login" method="post">
<div>
<label>用户</label>
<input type="text" name="username">
</div>
<div>
<label>密码</label>
<input type="password" name="pwd">
</div>
<div>
<input type="submit" value="登录">
</div>
</form>
</body>
</html>
2.编写Servlet处理请求
/**
* 在Servlet中接收表单参数
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
/*
* 用户浏览器发起的 Post 请求被Tomcat接收,
* Tomcat将请求信息解析到 Request 对象中。
* 任何请求信息,都可以从Request对象中获取
* 如获取请求参数:request.getParamter("username")
* paramter: 参数
*/
//setCharacterEncoding通知Request对象
//在解析 请求Body 时候使用UTF-8编码
//必须在 getParameter 方法调用之前设置
request.setCharacterEncoding("UTF-8");
String name=request.getParameter("username");
System.out.println("name="+name);
String pwd=request.getParameter("pwd");
System.out.println("pwd="+pwd);
response.setContentType(
"text/html; charset=UTF-8");
PrintWriter out=response.getWriter();
out.println("<html><body>");
//简易密码验证逻辑
if(name.equals("tom") && pwd.equals("123")) {
out.println("<h1>登录成功</h1>");
}else {
out.println("<h1>登录失败</h1>");
}
out.println("</body></html>");
}
}
获取get请求案例:
-
编写Servlet
/**
* 处理get请求参数当浏览器的get请求发送到Tomcat服务器时候,Tomcat会
* 解析请求头部,将请求头部数据存储到Request对象中传递到 Servlet。在Servlet中可以利用getParamter方法获取get请求参数
*/
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
//获取get请求参数时候,如果key对应的参数不存在就返回null
//request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String age = request.getParameter("age");
String pwd = request.getParameter("pwd");
System.out.println("name="+name);
System.out.println("age="+age);
System.out.println("pwd="+pwd);
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html></body>");
out.println("<h1>收到get参数!</h1>");
out.println("</body></html>");
}
}
2.测试
http://localhost:8080/Servlet02/test?name=赵子龙&age=18
post请求中文编码解析
- request对象会在第一次调用getParamter方法时候解析post请求参数。
- 在第一次调用getParamter之前设置解析编码就可以解决post请求编码问题。
- request.setCharacterEncoding("UTF-8");
get请求中文编码解析
- Tomcat会在创建request对象之前解析get请求参数,所以设置request的编码对get请求无效。
- 修改Tomcat的配置参数,可以解决处理get请求中文编码解析问题。
<Connector URIEncoding="UTF-8" ...
配置Tomcat7:
<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
读取请求参数值
a.方式一
String request.getParameter(String paranName)
b.方式二
String [] request.getParameterValues(String paramName)
注:当有多个请求参数名相同的时候,使用该方法.
Servlet容器如何处理请求资源路径?
比如,在浏览器地址栏输入
http://ip:port/servlet-day04/abc.html
step1.容器会认为访问的是一个Servlet
从web.xml中去查找 是否有匹配的servlet
step2.匹配方式:
方式一:精确匹配
请求地址与url-pattern完全一致.
方式二:通配符匹配
<url-pattern>/*</url-pattern>
注:*匹配零个或多个字符.
方式三:后缀匹配
<url-pattern>*.do</url-pattern>
注:匹配所有.do结尾的请求
step3.如果找不到匹配的Servlet,则容器会对应查找对应的文件
让一个Servlet处理多种请求
step1.使用后缀匹配,比如:
<url-pattern>*.do</url-pattern>
step2.分析请求资源路径,依据请求的不同,进行相应的处理.
Servlet的生命周期
1.什么是Servlet的生命周期?
Servlet容器如何创建Servlet实例,如何对其进行初始化,如何调用其方法来处理请求,以及如何其实例整个过程.即Servlet容器如何管理Servlet
2.Servlet生命周期分成哪几个阶段?
1)实例化 a.什么时候实例化?
情形一(默认):容器收到请求之后,才会创建。
情形二: 容器启动之后,立即创建。需要配置:
b.注意:容器在默认情况下,只会创建一个实例。
a.实例化
I.什么是实例化?
容器调用Servlet的构造器,创建Servlet对象.
II.什么时候实例化?
情形1:容器收到请求之后创建
情形2:容器启动之后,立即创建(需要相应的配置)
注:容器只会创建一个实例
b.初始化
I.什么是初始化?
容器在创建好servlet对象之后,会立即调用该对象的 init()方法。
II.init方法
II1.GenericServlet已经提供了init方法的实现.
(了解)将容器传递过来的ServletConfig对象保存下来,并且提供了getServletConfig方法,用来获得ServletConfig对象.
II2.init方法只会执行一次.
II3.可以override init()方法来扩展自己的初始化处理逻辑.
II4.初始化参数
c.就绪(调用)
I.什么是就绪?
容器调用Servlet对象的service方法处理请求.
II.service方法
II1.HttpServlet已经提供了service方法的实现:
依据请求类型调用相应的方法来处理,比如get请求调用doGet方法,post方法请求调用doPost方法. 可以override doGet和doPost方法 或者也可以override service方法.
d.销毁
I.什么是销毁?
当服务器关闭或者当前web应用被移出容器时,服务器会销毁每一个servlet,在销毁servlet之前,会调用它的destory()方法,执行销毁前的逻辑,一般用于释放该servlet占用的资源,如打开的流.
容器在删除Servlet对象之前,会调用该对象的destroy方法.
II.该方法只会执行一次.
生命周期相关的几个接口与类(了解)
1.Servlet接口
init()
service()
destroy()
2.GenericServlet抽象类
实现了Servlet接口(实现了init,destroy方法)
3.HttpServlet抽象类
继承了GenericServlet(实现了service方法)
重定向
1.什么是重定向?
服务器通知浏览器向一个新的地址发送请求
注:服务器可以发送一个302状态码和一个Location消息头(该消息头的值是一个地址,称之为重定向地址)给浏览器,浏览器收到之后,会立即向重定向地址发送请求.
2.如何重定向
response.sendRedirect(String url).
注:url就是重定向地址
重定向之前,服务器会清空response对象上存放的数据
3.特点
a.重定向地址是任意的
b.重定向之后,浏览器的地址栏会发生变化
ServletConfig讲解
1.1、配置Servlet初始化参数
在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
<servlet>
2 <servlet-name>ServletConfigDemo1</servlet-name>
3 <servlet-class>gacl.servlet.study.ServletConfigDemo1</servlet-class>
4 <!--配置ServletConfigDemo1的初始化参数 -->
5 <init-param>
6 <param-name>name</param-name>
7 <param-value>gacl</param-value>
8 </init-param>
9 <init-param>
10 <param-name>password</param-name>
11 <param-value>123</param-value>
12 </init-param>
13 <init-param>
14 <param-name>charset</param-name>
15 <param-value>UTF-8</param-value>
16 </init-param>
17 </servlet>
1.2、通过ServletConfig获取Servlet的初始化参数
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,我们通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
例如:
package gacl.servlet.study;
2
3 import java.io.IOException;
4 import java.util.Enumeration;
5 import javax.servlet.ServletConfig;
6 import javax.servlet.ServletException;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10
11 public class ServletConfigDemo1 extends HttpServlet {
12
13 /**
14 * 定义ServletConfig对象来接收配置的初始化参数
15 */
16 private ServletConfig config;
17
18 /**
19 * 当servlet配置了初始化参数后,web容器在创建servlet实例对象时,
20 * 会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,
21 * 将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以
22 * 得到当前servlet的初始化参数信息。
23 */
24 @Override
25 public void init(ServletConfig config) throws ServletException {
26 this.config = config;
27 }
28
29 public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
31 //获取在web.xml中配置的初始化参数
32 String paramVal = this.config.getInitParameter("name");//获取指定的初始化参数
33 response.getWriter().print(paramVal);
34
35 response.getWriter().print("<hr/>");
36 //获取所有的初始化参数
37 Enumeration<String> e = config.getInitParameterNames();
38 while(e.hasMoreElements()){
39 String name = e.nextElement();
40 String value = config.getInitParameter(name);
41 response.getWriter().print(name + "=" + value + "<br/>");
42 }
43 }
44
45 public void doPost(HttpServletRequest request, HttpServletResponse response)
46 throws ServletException, IOException {
47 this.doGet(request, response);
48 }
49
50 }
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LifeServlet extends HttpServlet{
public LifeServlet() {
System.out.println("LifeServlet's constructor");
}
@Override
public void init() throws ServletException {
System.out.println("LifeServlet's init()");
}
@Override
public void destroy() {
System.out.println("LifeServlet's destroy()");
}
public void doGet(HttpServletRequest request,HttpServletResponse response){
System.out.println("LifeServet's service");
/*
* 通过继承自GenericServlet的方法获得ServletConfig对象.
*/
ServletConfig config=getServletConfig();
/*
* 读取初始化参数
*/
String company=config.getInitParameter("company");
System.out.println("公司:"+company);
}
}
运行结果如下:
ServletContext对象
WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
ServletContext的应用
3.1、多个Servlet通过ServletContext对象实现数据共享
范例:ServletContextDemo1和ServletContextDemo2通过ServletContext对象实现数据共享
package gacl.servlet.study;
2
3 import java.io.IOException;
4 import javax.servlet.ServletContext;
5 import javax.servlet.ServletException;
6 import javax.servlet.http.HttpServlet;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9
10 public class ServletContextDemo1 extends HttpServlet {
11
12 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14 String data = "xdp_gacl";
15 /**
16 * ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,
17 * 可以通过ServletConfig.getServletContext方法获得ServletContext对象。
18 */
19 ServletContext context = this.getServletConfig().getServletContext();//获得ServletContext对象
20 context.setAttribute("data", data); //将data存储到ServletContext对象中
21 }
22
23 public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
25 doGet(request, response);
26 }
27 }
package gacl.servlet.study; 2 3 import java.io.IOException; 4 import javax.servlet.ServletContext; 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 public class ServletContextDemo2 extends HttpServlet { 11 12 public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { 14 ServletContext context = this.getServletContext(); 15 String data = (String) context.getAttribute("data");//从ServletContext对象中取出数据 16 response.getWriter().print("data="+data); 17 } 18 19 public void doPost(HttpServletRequest request, HttpServletResponse response) 20 throws ServletException, IOException { 21 doGet(request, response); 22 } 23 } 复制代码
先运行ServletContextDemo1,将数据data存储到ServletContext对象中,然后运行ServletContextDemo2就可以从ServletContext对象中取出数据了,这样就实现了数据共享,如下图所示:
获取WEB应用的初始化参数
在web.xml文件中使用<context-param>标签配置WEB应用的初始化参数,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
2 <web-app version="3.0" 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
3 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
4 <display-name></display-name>
5 <!-- 配置WEB应用的初始化参数 -->
6 <context-param>
7 <param-name>url</param-name>
8 <param-value>jdbc:mysql://localhost:3306/test</param-value>
9 </context-param>
10
11 <welcome-file-list>
12 <welcome-file>index.jsp</welcome-file>
13 </welcome-file-list>
14 </web-app>
获取Web应用的初始化参数,代码如下:
package gacl.servlet.study;
2
3 import java.io.IOException;
4 import javax.servlet.ServletContext;
5 import javax.servlet.ServletException;
6 import javax.servlet.http.HttpServlet;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9
10
11 public class ServletContextDemo3 extends HttpServlet {
12
13 public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
15
16 ServletContext context = this.getServletContext();
17 //获取整个web站点的初始化参数
18 String contextInitParam = context.getInitParameter("url");
19 response.getWriter().print(contextInitParam);
20 }
21
22 public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
24 doGet(request, response);
25 }
26
27 }