Servlet总结一
HttpServlet
想要实现一个servlet必须继承这个类,其实一个servlet就是一个java文件,但是这个类必须是继承HttpServlet。
生命周期
servlet的生命周期是从创建到毁灭的一个过程,具体的过程如下:
- Servlet 通过调用
init ()
方法进行初始化。- Servlet 调用
service()
方法来处理客户端的请求,但是在这一步还是要用到具体的实现的两个方法,分别是doPost(),doGet()- Servlet 通过调用
destroy()
方法终止(结束)。- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
常用的方法
init()
初试化方法
doGet(HttpServletRequest request,HttpServletResponse response)
处理get请求的方法
doPost(HttpServletRequest request,HttpServletResponse response)
处理post请求的方法
destroy()
最后销毁
Enumeration<E> getInitParameterNames()
该方法从 servlet 的 ServletConfig 对象获取所有的参数名称
public String getInitParameter(String name)
该方法从 servlet 的ServletConfig
对象获取指定参数的值 name是指定的param-name
的值,返回的param-value
的值,具体的使用如下:
<servlet>
<display-name>ServletConfigDemo</display-name>
<servlet-name>ServletConfigDemo</servlet-name>
<servlet-class>com.ServletConfigDemo</servlet-class>
<init-param>
<param-name>username</param-name> //定义的name
<param-value>陈加兵</param-value> //定义的value
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ServletConfigDemo</servlet-name>
<url-pattern>/ServletConfigDemo</url-pattern>
</servlet-mapping>
//下面只是一个servlet类中的init()方法,一般否是在init()方法中获取
public void init() throws ServletException {
username=this.getInitParameter("username"); //根据指定的名称获取参数的值
enumeration=this.getInitParameterNames(); //获取枚举对象
while(enumeration.hasMoreElements()){ //通过枚举的方法获取其中的所有的值
System.out.println(this.getInitParameter((String) enumeration.nextElement()));
}
}
ServletConfig getServletConfig()
返回一个ServletConfig对象,这个方法在后面讲到ServletConfig类的时候回详细的说到
ServletContext getServletContext()
返回一个ServletContext对象,这个和ServletConfig类一样重要,在后面会详细讲解
HttpServletRequest
这是servlet容器中用来处理请求的类,并且该对象作为一个参数传给doGet,doPost方法中
常用的方法
getParameter(String name)
获取表单中的值,name是input中定义的name值,如果不存在返回null,否则返回的字符串 String[]
getParameterValues(String name)
获取表单中有多个name相同的值,例如多选列表,复选框
Enumeration getParameterNames()
返回所有请求中的参数,返回的是一个枚举对象,可以通过对应的方法进行列出所有的参数
//下面将会详细讲解上面三个方法的使用法,这三个参数是针对表单的,因此需要结合表单讲解,我们将会在index.jsp文件中定义表单
//index.jsp文件的内容如下:
<form action="ServletDemo" method="post"> //servletDemo是要处理该请求的servlet的url,使用的是相对路径
username: <input type="text" name="username"> <br>Password:
<input type="password" name="pw"> <br>
<input type="submit" value="提交"> <br> <label>hobby:</label>
<input type="checkbox" name="hobby" value="1">swing <input
type="checkbox" name="hobby" value="2">dancing <input
type="checkbox" name="hobby" value="3">song
</form>
//下面是ServletDemo中的部分代码
String username = request.getParameter("username"); //获取username的值
String pw = request.getParameter("pw"); //获取password的值
//获取所有复选框的值
String[] hobbies=request.getParameterValues("hobby");
for(String hobby:hobbies){
System.out.println(hobby);
}
//获得所有的元素的name属性的名称,返回的是一个枚举的对象
Enumeration enumeration = request.getParameterNames();
while (enumeration.hasMoreElements()) {
String paramsString = (String) enumeration.nextElement(); //获取其中的每一名称
System.out.println(request.getParameter(request.getParameter)); //根据名称获取其中的值
}
Enumeration getHeaderNames()
获取所有请求头中的参数的名称,返回的是一个枚举对象String getHeader(String name)
根据请求头中的名称获取对应名称的请求内容
//获取所有请求头的名称,返回的是一个枚举对象
Enumeration enumeration=request.getHeaderNames();
while (enumeration.hasMoreElements()) {
String name=(String) enumeration.nextElement();
String value=request.getHeader(name); //根据名称返回对应的值
System.out.println(name+":"+value);
}
String getContextPath()
获取应用程序的环境路径,就是上一级目录String getMethod()
返回请求的方式 Get PostString getQueryString()
返回请求行中的参数部分StringBuffer getRequestURL()
返回完整的URLString getRequestURI()
返回请求行中的资源名部分getRemoteAddr
方法返回发出请求的客户机的IP地址。getRemoteHost
方法返回发出请求的客户机的完整主机名。getRemotePort
方法返回客户机所使用的网络端口号。getLocalAddr
方法返回WEB服务器的IP地址。getLocalName
方法返回WEB服务器的主机名。
请求转发与包含
请求转发相当于一个重定向,但是这个又和重定向不同的是:请求转发是在web容器中进行的,因此浏览器的地址栏并不会改变,但是重定向是要求浏览器重新请求另一个url,因此可以在地址栏清楚的看到地址的变化
请求转发使用的是
HttpServletRequest
中的getRequestDispatcher
方法,下面将会详细介绍
getRequestDispatcher
RequestDispatcher getRequestDispatcher(String path)
返回的是一个RequestDispatcher
对象,path是指定转发的url,可以是绝对url或者是相对url
RequestDispatcher
定义接收来自客户端的请求并将它们发送到服务器上的任何资源(比如 servlet、HTML 文件或 JSP 文件)的对象。servlet 容器可创建 RequestDispatcher 对象,该对象被用作包装位于特定路径上的服务器资源或通过特定名称给定的服务器资源的包装器。
void forward(ServletRequest request, ServletResponse response)
执行转发请求,因为继承关系,因此其中的参数也是可以是HttpServletRequest
和HttpServletResponse
对象
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取表单中的值
String name=request.getParameter("username");
String password=request.getParameter("password");
//上面虽然获取了其中的值,但是不可以此时对浏览器进行响应
RequestDispatcher dispatcher=request.getRequestDispatcher("Demo2");
dispatcher.forward(request, response);
}
注意: 在转发前后不可以对浏览器进行响应,否则会出现错误,其中forward传入的参数是当前的request和response,也就是说在转发之后的文件之中还是可以获取信息的(请求头,表单)
void include(ServletRequest request, ServletResponse response)
包含转发
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取表单中的值
String name=request.getParameter("username");
String password=request.getParameter("password");
Cookie cookie=new Cookie("age", "22");
response.addCookie(cookie);
PrintWriter pw=response.getWriter();
pw.println("在转发之前先对浏览器进行响应");
//上面可以看出这里对浏览器进行了响应,使用include可以在转发之前或者之后对浏览器进行响应
RequestDispatcher dispatcher=request.getRequestDispatcher("Demo2");
dispatcher.include(request, response);
}
forward和include的区别
forward
在转发之前和之后是不可以对浏览器进行响应的,但是include
可以。使用include
时,如果同时进行了响应,那么会同时响应在同一网页中,会出现在同一个页面中
相同点
- 请求转发后地址栏都不会出现改变
- 请求转发过后会重新回到当前的servlet容器中,因此如果想要在当前的servlet容器中处理一些东西是可以实现的,下面来看一个例子
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取表单中的值
String name=request.getParameter("username");
String password=request.getParameter("password");
//上面虽然获取了其中的值,但是不可以此时对浏览器进行响应
RequestDispatcher dispatcher=request.getRequestDispatcher("Demo2");
dispatcher.forward(request, response);
System.out.println(username); //这个语句当转发请求处理完成之后会返回到这里执行这句话
}
传递数据
就像写到
scrapy
爬虫的时候,有时候一个数据会传入到下一个函数中使用,因此需要一个机制携带过去。这里可以使用HttpServletRequest
中的setAttribute
方法,详细使用如下:
public void setAttribute(String name, Object o)
这里其实相当于传入的是一个键值对,name是key,o是value
public void removeAttribute(String name)
根据键值的name移除数据
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 设置编码,这个是通过浏览器访问时能够实现中文显示的功能
response.setContentType("text/html;charset=UTF-8");
//设置和浏览器相应的编码方式,以便在控制台上输出中文,否则将会乱码显示
request.setCharacterEncoding("UTF-8");
String data="大家好,我是陈加兵";
request.setAttribute("data",data); //向请求中传入数据,这个是以键值对存在的,前面的是key,后面的参数是value
//将请求转发给HttpServletDemo的servlet文件处理
RequestDispatcher dispatcher=request.getRequestDispatcher("HttpServletResponseDemo");
//如果转发成功,注意这里的转发,地址栏的网址并不会改变
if(dispatcher!=null){
dispatcher.forward(request, response);
}
}
//下面是HttpServletResponseDemo的处理代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8"); //设置响应内容
request.setCharacterEncoding("UTF-8"); //设置接受的编码
//接收请求转发传递的data数据
String data=(String) request.getAttribute("data");
PrintWriter pWriter=response.getWriter();
pWriter.println(data+"<br/>");
//移除这个键值对 ,下面在访问这个数据就会显示不存在了
request.removeAttribute("data");
pWriter.close();
}
HttpServletResponse
这个类是用于对浏览器进行响应的
常用的方法
PrintWriter getWriter()
返回一个PrintWriter对象,可以将字符串发送到客户端addCookie(Cookie cookie)
将指定的cookie添加到响应中,这个是直接添加到set-cookie中,用于存储一些信息
Cookie cookie=new Cookie("age", "22");
cookie.setMaxAge(7*24*60*60); //设置cookie的失效时间(秒为单位)
response.addCookie(cookie); //添加cookie
sendError(int src)
将指定的错误信息发送到客户端 比如401,302....sendError(int sec,String message)
发送错误信息的同时,还发送提醒的信息messagesendRedirect(String url)
网页重定向,url是重定向的网址,但是也可以是相对的urlServletOutputStream getOutputStream()
返回适用于在响应中编写二进制数据的 ServletOutputStream。
ServletConfig
在
web.xml
中对于每一个Servlet的设置web容器会为其生成一个ServletConfig
作为代表对象,你可以从该对象中取得设置在web.xml中的Servlet初始参数
常用方法
String getInitParameter(String name)
根据属性的名称获取指定的值
Enumeration getInitParameterNames()
获取该servlet中设置的所有的属性的名称(并不是设置的初始值)
ServletContext getServletContext()
获取ServletContext对象
设置和取得初始参数
ServletConfig
相当于web.xml中个别Servlet设置代表对象,这意味着可以从ServletConfig中取得Servlet设置信息。ServletConfig定义了getInitParameter()
、getInitParameterNames()
方法,可以取得设置的Servlet的初始参数
设置初始参数
直接在web.xml中定义如下:
<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>Demo3</servlet-name>
<servlet-class>com.Demo3</servlet-class>
<init-param> //定义标签
<param-name>username</param-name> //定义的name
<param-value>陈加兵</param-value> //定义的value
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
取得初始参数
第一种方法:直接使用带有ServletConfig对象为参数的init直接获取
public void init(ServletConfig config) throws ServletException {
// username=config.getInitParameter("username"); //单独的获取每一个值
// password=config.getInitParameter("password");
//首先获取所有的初始参数的名称
Enumeration enumeration=config.getInitParameterNames();
while(enumeration.hasMoreElements()){
String name=(String)enumeration.nextElement(); //获取每一个值
if(name.equals("username")){
username=config.getInitParameter(name);
}else if (name.equals("password")) {
password=config.getInitParameter(name);
}
}
}
第二种:使用
HttpServlet
的getServletConfig()
方法直接获取ServletConfig对象,然后再获取参数
public void init() throws ServletException {
ServletConfig config=this.getServletConfig(); //获取ServletConfig对象
username=config.getInitParameter("username"); //获取参数的值
password=config.getInitParameter("password");
}
ServletContext
ServletContext
是整个web应用程序运行之后的代表对象,这是一个全局的对象,一个web项目中的所有Servlet文件都是可以共享这个数据的,因此这个有着很大的作用。
- 有人说这个不是和
ServletConfig
一样的用法吗,其实不然,ServletConfig
并不是这个web程序的全局变量,它所设置的值只是对当前的servlet共享,并不能对web项目中的所有的servlet文件共享
常用方法
String getInitParameter(String name)
获取指定名称的属性值
Enumeration getInitParameterNames()
获取所有已经设置的属性的名称
void setAttribute(String name, Object object)
将对象绑定到此 servlet 上下文中的给定属性名称。如果已将指定名称用于某个属性,则此方法将使用新属性替换具有该名称的属性。
Object getAttribute(String name)
根据指定的属性名称获取绑定的值(需要进行强转)
void removeAttribute(String name)
解除绑定的数据
设置初始参数
这个和
ServletConfig
是一样的,都是在web.xml中设置的,但是这个是设置在<servlet></servlet>
的外面的,并不是针对单独的一个servlet
来设置的,因此是全局共享的
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>web2</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!--全局变量,对工程中的所有的Servlet都是共享的-->
<context-param>
<param-name>context_name</param-name>
<param-value>context_value</param-value>
<!--在每一对context-param中只能定义一个变量的值-->
</context-param>
<context-param>
<param-name>username</param-name>
<param-value>陈加兵</param-value>
</context-param>
<servlet>
<servlet-name>Demo1</servlet-name>
<servlet-class>com.Demo1</servlet-class>
</servlet>
<servlet>
<servlet-name>Demo2</servlet-name>
<servlet-class>com.Demo2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo1</servlet-name>
<url-pattern>/Demo1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo2</servlet-name>
<url-pattern>/Demo2</url-pattern>
</servlet-mapping>
</web-app>
获取设置的参数
- 第一种方法:使用无参初始化的方法
init()
,结合父类HttpServlet
的getServletContext()
的方法获取ServletContext
对象
//使用无参构造函数
public void init() throws ServletException {
ServletContext context=this.getServletContext();
//根据属性的名称获取指定的值
String value=context.getInitParameter("username");
System.out.println(value);
//获取所有的属性的名称的枚举对象
Enumeration enumeration=context.getInitParameterNames();
while(enumeration.hasMoreElements()){
//获取属性的每一个名称
String name=(String) enumeration.nextElement();
//根据名称获取所有的值
System.out.println(name+" = "+context.getInitParameter(name));
}
}
- 第二种方法:使用有参初始化方法
init(ServletConfig config)
,结合ServletConfig
的getServletContext()
方法获取对象
//使用有参构造方法
public void Init(ServletConfig config){
//调用ServletConfig中的方法获取对象
ServletContext context=config.getServletContext();
//获取属性的值
String value=context.getInitParameter("username");
System.out.println(value);
}
绑定属性
有人可能会说如果想用共享数据在web.xml设置有点繁琐,这里可以直接绑定属性,然后就可以在整个web项目中共享这个绑定的属性了
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//获取对象(这是父类HttpServlet中的一个方法)
ServletContext context=this.getServletContext();
//count表示访问页面的次数,在这里设置了属性可以全局共享该数据,意思就是在一个项目中的所有的servlet都是可以访问到该数据的
Integer count=(Integer) context.getAttribute("count"); //获取设置的属性值
//如果为空,表示该属性还没有被设置,因此这是第一次访问该页面
if(count==null){
count=1;
context.setAttribute("count", 1); //初始值为1,表示访问网页1次
}else { //否则表示已经不是第一次访问网页了,因此需要++1
context.setAttribute("count", ++count);
}
PrintWriter pWriter=response.getWriter();
pWriter.println("该页面已经被访问了"+count+"次了......");
}