Servlet总结
1.Servlet接口
创建HelloServlet实现Servlet接口,作为实例代码
1.Servlet生命周期方法:以下方法都是Servlet容器负责调用(tomcat就是一个Servlet容器)
1.构造方法
只要第一次请求Servlet时,创建实例,调用构造器.说明Servlet是单实例的
public HelloServlet() {
// TODO Auto-generated constructor stub
System.out.println("HelloServlet's constructor");
}
2.init()方法:只被调用一次,在创建好实例后立即被调用.用于初始化当前的构造方法
@Override
public void init(ServletConfig config) throws ServletException {
}
3.service()方法:被调用多次,每次请求都会调用service方法.实际用于响应请求
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("service");
}
4.destroy()方法:只被调用一次,在当前Servlet所在的WEB应用被卸载前调用.用于释放当前Servlet所占用的资源
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("destroy");
}
2.servlet配置web.xml
每创建一个Servlet需要在web.xml中配置相关信息
<servlet>
<!-- Servlet的名字 -->
<servlet-name>helloServlet</servlet-name>
<!-- Servlet的java文件的路径 -->
<servlet-class>com.kingkiller.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- Servlet的名字,需和上面的相同 -->
<servlet-name>helloServlet</servlet-name>
<!-- Servlet的url路径 -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
load-on-startup参数:
1.配置在servlet节点中
2.可以指定Servlet被创建的时机,若为负数,则在第一次请求时被创建,若为0或正数,则在当前WEB应用被Servlet容器加载时创建实例,且数值越小越早被创建
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.kingkiller.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
3…Servlet映射的细节
1.同一个Servlet可以被映射到多个URL上,即多个元素的子元素的设置可以是同一个Servlet的注册名。
2.在Servlet映射到URL中也可以使用通配符,但是只能有两种固定的格式,一种格式是".拓展名",另一种格式是以正斜杠(/)开头并以"/*"结尾
2.ServletConfig
封装了Servlet的配置信息,并且可以获取ServletContext对象
1.获取参数的方法
1.getInitParameter(String name):获取指定参数名的初始化参数
2.getInitParameterNames():获取参数名组成的Enumeration对象
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
String user = config.getInitParameter("user");
System.out.println("user:"+user);
Enumeration<String> names = config.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
System.out.println("name"+name);
}
}
2.获取Servlet名字的方法
1.getServletName:获得注册的Servlet的名字
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
String servletName = config.getServletName();
System.out.println(servletName);
}
3.获取Context的方法
1.getServletContext:返回这个Servlet的ServletContext对象。
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
ServletContext servletContext = config.getServletContext();
}
3.ServletContext接口
1.可以由servletConfig获取
2.对象代表当前WEB应用:可以认为ServletContext是当前WEB应用的一个大管家,可以从中获取到WEB应用的各个方面的信息
1.获取当前WEB应用的初始化参数
1.在web.xml配置当前WEB应用的初始化参数
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.kingkiller.HelloServlet</servlet-class>
<init-param>
<param-name>user</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>1234</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
注意放在load-on-startup前
2.常用方法:
getInitParameter(): Returns a String
containing the value of the named context-wide initialization parameter, or null
if the parameter does not exist.
getInitParameterNames(): Returns the names of the context’s initialization parameters as an Enumeration
of String
objects, or an empty Enumeration
if the context has no initialization parameters.
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
ServletContext servletContext = config.getServletContext();
String driver = servletContext.getInitParameter("driver");
System.out.println("driver:"+driver);
Enumeration<String> names2 = servletContext.getInitParameterNames();
while (names2.hasMoreElements()) {
String name = names2.nextElement();
System.out.println(" -->" + name);
}
}
2.获取当前web应用的某一个文件在服务器上的绝对路径,而不是部署前的路径
1.getRealPath(String path): Returns a String
containing the real path for a given virtual path.
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
ServletContext servletContext = config.getServletContext();
String realPath = servletContext.getRealPath("/note.txt");
System.out.println(realPath);
}
3.获取当前WEB应用的名称
1.getContextPath(): Returns the context path of the web application.
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
ServletContext servletContext = config.getServletContext();
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
}
4.获取当前WEB应用的某一个文件对应的输入流
1.getResourceAsStream(String):Returns the resource located at the named path as an InputStream
object.
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
ServletContext servletContext = config.getServletContext();
try {
ClassLoader classLoader = getClass().getClassLoader();
InputStream is = classLoader.getResourceAsStream("jdbc.properties");
System.out.println("1." + is);
} catch (Exception e) {
// TODO: handle exception
}
try {
InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc/properties");
System.out.println("2." + is2);
} catch (Exception e) {
// TODO: handle exception
}
}
path的"/"为当前WEB应用的根目录
5.和attribute相关的方法
4.在Servlet中获取请求信息
Servlet的service()方法用于应答请求:因为每次请求都会调用service()方法
ServletRequest:封装了请求信息.可以从中获取到任何的请求信息.
ServletResponse:封装了响应信息,如果想给用户什么响应,具体可以使用该借口的方法实现
这两个接口的实现类都是服务器给予实现的,并在服务器调用service方法时传入
下面将会详细讲述ServletRequest和ServletResponse这两个接口
创建login.html做测试
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="longinServlet" method="post">
user:<input type="text" name="user"/>
password:<input type="password" name="password"/>
<br><br>
interesting:
<input type="checkbox" name="interesting" value="reading"/>Reading
<input type="checkbox" name="interesting" value="game"/>Game
<input type="checkbox" name="interesting" value="party"/>Party
<input type="checkbox" name="interesting" value="shopping"/>Shopping
<input type="checkbox" name="interesting" value="sport"/>Sport
<input type="checkbox" name="interesting" value="tv"/>TV
<input type="submit" value="提交"/>
</form>
</body>
</html>
5.ServletRequest接口
1.获取请求参数
1.String getParameter(String name):以一个String返回指定的参数的值,如果这个参数不存在返回空值.但若接收的参数值为多个时,只能接收第一个的值
2.Enumeration getParameterNames():返回所有的参数名的String对象列表,如果没有输入参数,则该返回一个空值
3.String[] getParameterValues(String name):通过一个String对象的数组返回指定参数的值,如果这个参数不存在,该方法返回一个空值
4.Map getParameterMap():返回请求参数的键值对,key:参数名,value:参数值.
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("请求来了");
System.out.println(request);
String user = request.getParameter("user");
String password = request.getParameter("password");
System.out.println(user+":"+password);
String interesting = request.getParameter("interesting");
System.out.println(interesting);
String[] interestings = request.getParameterValues("interesting");
for (String interest : interestings) {
System.out.println(interest);
}
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String val = request.getParameter(name);//因为这里用的是getParameter所有在传入多个参数时只获取到第一个
System.out.println(name + ":" + val);
}
Map<String, String[]> map = request.getParameterMap();
for (Entry<String, String[]> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + Arrays.asList(entry.getValue()));
}
}
2.获取请求的url
需要强转成其子类HttpServletRequest,再调用getRequestURI()方法
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String requestURI = httpServletRequest.getRequestURI();
System.out.println(requestURI);
}
3.获取请求方式
1.getMethod:也是HttpServletRequest里的方法
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String method = httpServletRequest.getMethod();
System.out.println(method);
}
4.若是一个GET请求,获取请求参数对应的字符串
即url中?后的部分
getQueryString()
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String queryString = httpServletRequest.getQueryString();
System.out.println(queryString);
}
5.获取Servlet的请求路径
即url-pattern
getServletPath()
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String servletPath = httpServletRequest.getServletPath();
System.out.println(servletPath);
}
6.和attribute相关的几个方法
6.ServletResponse接口
1.getWriter()
返回PrintWriter对象,调用该对象的print方法
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
out.println("helloworld");
}
2.设置响应的内容类型:
responseContentType()
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("application/msword");//设置响应类型为WORD文档,发送request请求后,会直接下载一个含有response内容的word文档
PrintWriter out = response.getWriter();
out.println("helloworld");
}
3.请求重定向
void sendRedirect(String location):此方法定义在HttpServletResponse中定义
7.GenericServlet
1.是一个Servlet,是Servlet接口和ServletConfig接口的实现类.但是是一个抽象类,其中的service方法为抽象方法
2.如果新建的Servlet程序直接继承GenericServlet会使开发更加的简洁
3.具体实现:
1.在GenericServlet里面,声明了一个ServletConfig类型的成员变量,
在init(ServletConfig)方法中对其初始化
2.利用了servletConfig成员变量的方法实现了ServletConfig接口的方法
3.还定义了一个init()方法,在init(ServletConfig)方法中对其调用,子类可以直接重写init(),在其中实现对Servlet的初始化
4.不建议直接覆盖init(Servlet),因为如果忘记编写super(ServletConfig),则会出现空指针异常
5.新建的init()并非Servlet的生命周期方法,而init(ServletConfig)是生命周期方法
下面我们自已创建一个MyGenericServlet(不包含两个日志方法)
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public abstract class MyGenericServlet implements Servlet,ServletConfig{
/**
* 下面是实现Servlet的方法
*/
private ServletConfig config;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return config;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
this.config = config;
init();
}
private void init() {
// TODO Auto-generated method stub
}
@Override
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
/**
* 下面是实现ServletConfig的方法
*/
@Override
public String getInitParameter(String name) {
// TODO Auto-generated method stub
return config.getInitParameter(name);
}
@Override
public Enumeration<String> getInitParameterNames() {
// TODO Auto-generated method stub
return config.getInitParameterNames();
}
@Override
public ServletContext getServletContext() {
// TODO Auto-generated method stub
return config.getServletContext();
}
@Override
public String getServletName() {
// TODO Auto-generated method stub
return config.getServletName();
}
}
8.HttpServlet
1.是一个Servlet,继承自GenericServlet,针对HTTP协议定制
2.在service()方法中直接把ServletRequest和ServetResponse转为HttpServletRequest和HttpServletResponse
并调用了重载的service(HttpServletRequest,HttpServletResponse)方法
在service(HttpServletRequest,HttpServletResponse)获取了侵权方式:request.getMethod()根据请求方式又创建 doPost,doGet方法
3.实际开发中,直接继承HttpServlet,并根据请求方式覆写doXxx()方法接口
4.好处:直接由针对性的覆盖doXxx()方法;直接使用HttpServletRequest合HttpServletResponse,不再需要强转
下面我们创建自己的MyHttpServlet进行测试
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 针对HTTP协议定义的一个Servlet基类
* @author Administrator
*
*/
public class MyHttpServlet extends MyGenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
// TODO Auto-generated method stub
if (req instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest)req;
if (res instanceof HttpServletResponse) {
HttpServletResponse response = (HttpServletResponse) res;
service(request, response);
}
}
}
public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
//1.获取请求方式
String method = request.getMethod();
//2.根据请求方式再调用对应的处理方法
if ("GET".equalsIgnoreCase(method)) {
doGet(request,response);
}
if ("POST".equalsIgnoreCase(method)) {
doPost(request,response);
}
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) {
// TODO Auto-generated method stub
}
public void doGet(HttpServletRequest request,
HttpServletResponse response) {
// TODO Auto-generated method stub
}
}