Servlet基础
先介绍JSP页面的运行原理:当用户请求一个JSP页面时,Tomcat服务器自动生成Java文件、编译Java文件,并用编译得到的字节码文件在服务器端创建一个对象来响应用户的请求。
JSP的根基是Servlet技术,该技术的核心就是在服务器端创建能响应用户请求的对象,被创建的对象习惯上称作一个servlet对象。
JSP技术不是Java Servlet技术的全部,只是Servlet技术的一个成功应用。JSP技术屏蔽了servlet对象创建的过程,使得Web程序设计者只需关心JSP页面本身的结构,设计好各种标记。
以下部分转载自:http://howtodoinjava.com/servlets/complete-java-servlets-tutorial/
一个Servlet Demo
package com.howtodoinjava.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyFirstServlet extends HttpServlet {
private static final long serialVersionUID = -1915463532411657451L;
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
// Write some content
out.println("<html>");
out.println("<head>");
out.println("<title>MyFirstServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h2>Servlet MyFirstServlet at " + request.getContextPath() + "</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//Do some other work
}
@Override
public String getServletInfo() {
return "MyFirstServlet";
}
}
向web.xml注册关于这个servlet的相关信息
<?xml version="1.0"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<welcome-file-list>
<welcome-file>/MyFirstServlet</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>MyFirstServlet</servlet-name>
<servlet-class>com.howtodoinjava.servlets.MyFirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyFirstServlet</servlet-name>
<url-pattern>/MyFirstServlet</url-pattern>
</servlet-mapping>
</web-app>
- MyFirstServlet extends HttpServlet. This is mandatory because all servlets must be either a generic servlet that extends
javax.servlet.GenericServlet
or an HTTP servlet that extendsjavax.servlet.http.HttpServlet
. - Overriding
doGet()
anddoPost()
methods. These methods are defined inHttpServlet
class. Whenever a GET or POST request come, it is mapped to it’s respective method e.g. if you send a HTTP GET request to this servlet, thendoGet()
method is called. - There are some other useful methods as well which you can override to control the application in runtime e.g.
getServletInfo()
. HttpServletRequest
andHttpServletResponse
are default parameters to all doXXX() methods. We will learn more about these objects in later section.
Servlet对象的工作原理
servlet生命周期
servlet对象是javax.servlet包中HttpServlet类的子类的一个实例,由服务器负责创建并完成初始化工作。当多个用户请求一个servlet时,服务器为每个用户启动一个线程而不是启动一个进程,这些线程由服务器来管理。
一个servlet对象的生命周期主要由下列3个过程组成:
- 初始化servlet对象。servlet对象第一次被请求加载时,服务器初始化这个servlet对象,即创建一个servlet对象,这个对象调用init方法完成必要的初始化工作。
- 产生的servlet对象再调用service方法响应用户的请求。
- 当服务器关闭时,调用destroy方法,消灭servlet对象。
init方法只被调用一次,即在servlet第一次被请求加载时调用该方法。当后续的用户请求servlet服务时,web服务将启动一个新的线程,在该线程中,servlet对象调用service方法响应用户的请求,也就是说,每个用户的每次请求都导致service方法被调用执行,其执行过程分别运行在不同的线程中。
init方法
该方法可以重写。servlet对象第一次被请求加载时,服务器创建一个servlet对象,这个对象调用init方法完成必要的初始化工作。该方法在执行时,服务器会把一个ServletConfig类型的对象传递给init方法,这个对象就被保存在servlet对象中,直到servlet对象被消灭。这个ServletConfig对象负责向servlet传递服务设置信息,如果传递失败就会发生ServletException,Servlet对象就不能正常工作。
service方法
可以重写。当servlet对象成功创建和初始化后,该对象就调用service方法来处理用户的请求并返回响应。服务器将两个参数传递给该方法,一个HttpServletRequest类型的对象,该对象封装了用户的请求信息;另一个参数是HttpServletResponse对象,该对象用来响应用户的请求。
destroy方法
该方法是HttpServlet方法,一般不需要重写。当服务器终止服务时,destroy()方法会被执行,消灭servlet对象。
使用@WebServlet注解来开发Servlet
如果你不喜欢使用xml配置而喜欢注解的话,没关系,Servlets API同样提供了一些注解接口给你。你可以像下面的例子一样使用 @WebServlet 注解并且不需要在web.xml里为Servlet注册任何信息。容器会自动注册你的Servlet到运行环境,并且像往常一样处理它。
package com.howtodoinjava.servlets;
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;
@WebServlet(name = "MyFirstServlet", urlPatterns = {"/MyFirstServlet"})
public class MyFirstServlet extends HttpServlet {
private static final long serialVersionUID = -1915463532411657451L;
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
//Do some work
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//Do some other work
}
}
doGet和doPost
当服务器创建servlet对象后,该对象会调用init方法初始化自己,以后每当服务器在接受到一个servlet请求时,就会产生一个新线程,并在这个线程中让servlet对象调用service方法,而HttpServlet类所产生的service方法的功能是检查HTTP请求类型(get、post等),并在service方法中根据用户的请求方式,在service方法中对应地再调用doGet或doPost。因此一般不必重写service方法,但是可以在servlet中重写doGet和doPost方法来响应用户的请求。
重定向与转发
重定向的功能是将用户从当前页面或servlet定向到另一个JSP页面或servlet;转发的功能是将用户对当前JSP页面或servlet对象的请求转发给另一个JSP页面或servlet对象。
sendRedirect方法
重定向方法:void sendRedirect(String location)
RequestDispatcher对象
这个对象可以把用户对当前JSP页面或者servlet的请求转发给另一个JSP页面或者servlet,而且将用户对当前JSP页面或者servlet的请求和响应对象传递给所转发的JSP页面或servlet。
实现转发的步骤:
1、得到RequestDispather对象:
RequestDispatcher dispatcher = request.getRequestDispatcher("a.jsp");
2、转发:调用RequestDispatcher的forward方法。
dispatcher.forward(request,response);
两者区别:
重定向的目标页面或servlet对象无法使用request获取用户提交的数据。
如果是转发,用户在浏览器的地址栏中不能看到forward方法转发的页面的地址或servlet的地址,用户只能看到当前页面或servlet的地址。
传递Servlet初始化参数
现在的大多数应用都需要设置一些在应用/控制器(controller)启动时可以传递的配置参数(configuration parameters)。Servlet同样可以接受初始化参数,并在处理第一个请求前来使用它们来构建配置参数。
显然,你也可以在Servlet里硬编码配置值。但是这样做的话,在Servlet发生改动时你需要再次重新编译整个应用。没有人喜欢这样做。
<web-app>
<servlet>
<servlet-name>SimpleServlet</servlet-name>
<servlet-class>com.howtodoinjava.servlets.SimpleServlet</servlet-class>
<!-- Servlet init param -->
<init-param>
<param-name>name</param-name>
<param-value>value</param-value>
</init-param>
</servlet>
</web-app>
设置后,你就可以在代码里调用 getServletConfig.getInitializationParameter()
并传递参数名给该方法来使用参数。