Servlet(服务器端小程序)是使用Java语言编写的服务器端程序,可以像JSP一样,
生成动态的Web页面。Servlet主要运行在服务器端,并且由服务器调用执行,是一种按照
Servlet标准开发的类。
Servlet程序是对Java对CGI程序的实现,但是与传统CGI的多线程处理操作不同的是,
Servlet采用了多线程的处理方式,这样就使得Servlet程序的运行效率比传统的CGI更高;
而且Servlet还保留有Java的可移植性的特点,这样使得Servlet更易使用,功能也更加强大。
一."Hello World"
Servlet的类肯定要继承HttpServlet类,并且至少覆写doGet方法。
HelloServlet :
package com.zyy.servlet;
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 HelloServlet extends HttpServlet {
/**
*
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter print = resp.getWriter();
print.println("<center><h2>Hello World</h2></center>");
print.close();
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
web.xml:
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.zyy.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
注意:每次修改web.xml后都要重启服务器。
地址栏输入:http://127.0.0.1:8080/Servlet/helloServlet
二.Servlet与表单
表单提交的方式是post的话,那么就要覆写doPost()方法。
servlet_1.html:
<!DOCTYPE html>
<html>
<head>
<title>servlet_1.html</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
</head>
<body>
<form action="InputServlet" method="post">
<input type="text" name="info">
<input type="submit" value="提交">
</form>
</body>
</html>
InputServlet:
package com.zyy.servlet;
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 InputServlet extends HttpServlet {
/**
*
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter print = resp.getWriter();
String info = req.getParameter("info");
print.println("<center>" + info + "</center>");
print.close();
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
其实这里非常简单,我们依然可以使用单独的doGet()、单独的doPost()。但是这样用doPost
调用doGet的话,可以实现表单的通用处理,即使是get请求,服务器端这边也做成了doPost。
web.xml:
<servlet>
<servlet-name>input</servlet-name>
<servlet-class>com.zyy.servlet.InputServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>input</servlet-name>
<url-pattern>/html/InputServlet</url-pattern>
</servlet-mapping>
为什么是/html/InputServlet呢?
我的servlet_1.html是放在了html文件夹里,原来进到servlet_1.html的时候已经是
http://127.0.0.1:8080/html/servlet_1.html了,如果url-pattern 设置为
/InputServlet的话,提交后变成http://127.0.0.1:8080/InputServlet,这样就提
示404找不到资源的错误,也就是找不到servlet_1.html了。如果我们把此url-pattern就
为启动的钥匙,顺便还带你访问了html文件夹,这样就变成了/html/InputServlet。最终结
果就是http://127.0.0.1:8080/Servlet/html/InputServlet 。总结出一个规律:
要跳转的的页面如果不在根目录下,那么url-pattern就要在前面添加/xxx/xxx/Serlvet,直到配到
跳转页面的文件夹目录位置。
三.Servlet生命周期
1.加载Servlet
Web容器负责加载Servlet,当Web容器启动的时候或者是在第一次使用这个Servlet的
时候,容器会负责加载Servlet实例,但是用户必须通过web.xml文件描述指定Servlet的
位置,成功加载之后,Web容器会通过反射机制对Servlet进行实例化。
2.初始化
当一个Servlet被实例化之后,容器将调用init()方法初始化这个对象,初始化的目的是为
了让Servlet对象在处理客户端请求前完成一些初始化的工作,如建立数据库连接、读取资源文
件信息等等。如果初始化失败了,那么Servlet会被直接卸载。
3.处理服务
当有请求提交时,Servlet将调用service()方法进行处理。在service()方法中,Servlet
可以通过ServletRequest接受客户的请求,也可以利用ServletResponse设置响应信息。
4.销毁
当Web容器关系或检测到一个Servlet要从容器中删除的时候,会自动调用destory()方法,以
便让该实例释放掉所占的资源。
5.卸载
当一个Servlet调用完destory方法()后,此实例将等待被垃圾收集器所回收,如果需要再次使
用此Servlet时,会重新调用init()方法初始化。
这里不做过多介绍,这里提供一个
LifeCycleServlet:
package com.zyy.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LifeCycleServlet extends HttpServlet {
/**
*
*/
public void init() throws ServletException {
System.out.println("1.Servlet初始化 init()");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("2.Servlet服务 doGet() doPost()");
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
public void destroy() {
try {
System.out.println("3.Servlet销毁 destroy()");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
web.xml:
<servlet>
<servlet-name>life</servlet-name>
<servlet-class>com.zyy.servlet.LifeCycleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>life</servlet-name>
<url-pattern>/LifeCycleServlet</url-pattern>
</servlet-mapping>
四.Servlet取得初始化信息
web.xml配置初始化信息:
<servlet>
<servlet-name>init</servlet-name>
<servlet-class>com.zyy.servlet.InitParamServlet</servlet-class>
<init-param>
<param-name>initParam</param-name>
<param-value>CaMnter</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>init</servlet-name>
<url-pattern>/InitParamServlet</url-pattern>
</servlet-mapping>
InitParamServlet:
package com.zyy.servlet;
import java.io.IOException;
import java.io.PrintWriter;
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 InitParamServlet extends HttpServlet {
/**
*
*/
private String initParam = null;
public void init(ServletConfig config) throws ServletException {
this.initParam = config.getInitParameter("initParam");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter print = resp.getWriter();
String info = req.getParameter("info");
print.println("<center>" + initParam + "</center>");
print.close();
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
五.取得HttpSession和ServletContext(application)
SessionServlet:
package com.zyy.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionServlet extends HttpServlet {
/**
*
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("CaMnter", "Save you from anything 07");
System.out.println(session.getId());
System.out.println(session.getAttribute("CaMnter"));
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
web.xml:
<servlet>
<servlet-name>session</servlet-name>
<servlet-class>com.zyy.servlet.SessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>session</servlet-name>
<url-pattern>/SessionServlet</url-pattern>
</servlet-mapping>
Tomcat后台:
ServletContextServlet:
这个需要通过HttpServlet的父类GenericServlet来取得。即super.getServletContext() 。
package com.zyy.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletContextServlet extends HttpServlet {
/**
*
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletContext application = super.getServletContext();
System.out.println(application.getRealPath("/"));
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
web.xml:
<servlet>
<servlet-name>application</servlet-name>
<servlet-class>com.zyy.servlet.ServletContextServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>application</servlet-name>
<url-pattern>/ServletContextServlet</url-pattern>
</servlet-mapping>
Tomcat后台:
六.Servlet客户端跳转
可以使用HttpServletResponse中的sendRedirect()方法,但是只能保存session
和application范围的属性。
ClientRedirectServlet:
package com.zyy.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ClientRedirectServlet extends HttpServlet {
/**
*
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("CaMnter_sess", "sess_Save you from anything 07");
req.setAttribute("CaMnter_req", "req_Save you from anything 07");
resp.sendRedirect("servlet_2.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
servlet_2.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>servlet_2.jsp</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<center>
<h2>session: <%=session.getAttribute("CaMnter_sess") %> </h2>
<h2>request: <%=request.getAttribute("CaMnter_req") %> </h2>
</center>
</body>
</html>
web.xml:
<servlet>
<servlet-name>client</servlet-name>
<servlet-class>com.zyy.servlet.ClientRedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>client</servlet-name>
<url-pattern>/html/ClientRedirectServlet</url-pattern>
</servlet-mapping>
关于url-pattern的配置,上文的总结规律可以得出,这里不做多余的解释。
request为空,这是理所当然,response的跳转属于客户端跳转,request只能在服务器端
跳转下能保存,客户端跳转的情况下保存不了。客户端跳转只能保存session和application。
地址也变了。
七.Servlet服务器端跳转
需要依赖RequestDispatcher接口去完成服务器端跳转。
ServerRedirectServlet:
package com.zyy.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ServerRedirectServlet extends HttpServlet {
/**
*
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("CaMnter_sess", "sess_Save you from anything 07");
req.setAttribute("CaMnter_req", "req_Save you from anything 07");
RequestDispatcher requestDispatcher = req
.getRequestDispatcher("servlet_2.jsp");
requestDispatcher.forward(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
servlet_2.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>servlet_2.jsp</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<center>
<h2>session: <%=session.getAttribute("CaMnter_sess") %> </h2>
<h2>request: <%=request.getAttribute("CaMnter_req") %> </h2>
</center>
</body>
</html>
web.xml:
<servlet>
<servlet-name>server</servlet-name>
<servlet-class>com.zyy.servlet.ServerRedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>server</servlet-name>
<url-pattern>/html/ServerRedirectServlet</url-pattern>
</servlet-mapping>
能接收的到request,因为是服务器端跳转。地址没变。