目录
前言
JSP的根基是Servlet技术,该技术的核心就是tomcat服务器端创建响应用户请求的对象,被创建的对象习惯上被称为一个Servlet.
6.1 Servlet的部署,创建与运行
学习Servlet的首要任务是掌握咋样编写创建Servlet类,咋样保存这个Servlet类.
6.1.1 源文件及字节码文件
1.Servlet类
写一个创建Servlet的类就是编写提高特殊类的子类,这个特殊类就是javax.Servlet.http包中的httpservlet类.
参考代码如下:
package moon.sun; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Example6_1 extends HttpServlet{ public void init(ServletConfig config) throws ServletException{ super.init(config); } public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{ //设置响应的MIME类型: response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter();//获得向用户发送数据的输出流。 out.println("<html><body bgcolor = #ffccff>"); out.println("<h1>hello servlet,你好 servlet</h1>"); out.println("</body></html>"); } }
2.字节码文件的保存
保存java源文件时,保存类型为ANSI
编译代码为:
javac -cp servlet - api.jar moon\sun\Exaple6_1.java
6.1.2 编写部署文件 web.xml
Sevlet类的字节码文件保存到指定的目录后,必须为 Tomcat服务器编写一个部署文件,只有这样,Tomeat 服务器才会用 Servet类创建 servet对象。我们只需要知道XML文件是由标记组成的文本文件,使用该XML文件的系统应用程序的解释器可以解析XML文件标记中的数据。
参考代码为:
6.1.3 Servlet的创建与运行
servlet 由 Tomeat 服务器负责创建,Web 设计者只需为 Tomcat 服务器预备好 Servlet类,编写好相应的配置文件 web. xml,用户就可以根据 web. xml 部署文件来请求 Tomcat 服务器创建并运行一个 servlet。如果Tomcat 服务器没有名字为 hello 的 servlet,就会根据 web. xml 文件中 servlet 标记的子标记 servlet-class 指定的Servlet 类创建一个名字为 hello 的 servlet。因此,如果名字是 hello 的 servlet 被创建之后,修改 Java 源文件、编译得到新的 Servlet 类,并希望 Tomeat 服务器用新的 Servlet 类创建servlet,那么就要重新启动 Tomcat 服务器。当用户请求 Tomcat 服务器运行一个 servlet 时,必须根据 web. xml 文件中标记 url-pattern 指定的格式输入请求。
例如:
http://127.0.01:8080/ch6/lookHello
6.1.4 向servlet传递参数的值
在url-pattern中加入参数传递值.通过request.getParmeter(参数)来接收值.
参考代码:
package moon.sun;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.geom.*;
import javax.imageio.ImageIO;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_2 extends HttpServlet{
public void init(ServletConfig config) throws ServletException{
super.init(config);
}
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
double width = Double.parseDouble(request.getParameter("width"));
double height = Double.parseDouble(request.getParameter("height"));
response.setContentType("image/jpeg");
Ellipse2D ellipse=new Ellipse2D.Double(400-width/2,300-height/2,width,height);
BufferedImage image = getImage(ellipse);
try {
OutputStream outClient= response.getOutputStream();//指向用户端的输出流。
boolean boo =ImageIO.write(image,"jpeg",outClient);
}
catch(Exception exp){}
}
BufferedImage getImage(Shape shape){ //得到图形的图像
int width=800, height=600;
BufferedImage image =
new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.fillRect(0, 0, width, height);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(Color.blue);
g_2d.fill(shape);
return image;
}
}
6.2 servlet的工作原理
tomcat通过读取web.xml,然后创建servlet.
6.2.1 servlet对象的生命周期
一个 servlet 的生命周期主要由下列三个过程组成:
(1)初始化 servlet。 servlet 第一次被请求加载时调用该方法。即创建一个servlet这servlet 调用 init 方法完成必要的初始化工作。
(2)新诞生的 servlet 再调用 service 方法响应用户的请求。
(3)当服务器关闭时,调用 destroy 方法销毁 servlet。
6.2.2 init方法
该方法是 HttpServlet 类中的方法,可以在子类中重写这个方法。init 方法的声明格式是:
public void init(ServletConfig config) throws ServletException
6.2.3 service方法
该方法是 HttpServlet 类中的方法,可以在子类中直接继承该方法或重写这个方法service 方法的声明格式是:
public void service(HttpServletRequest request HttpServletResponse response) throw ServletException,IOException
6.2.4 destroy方法
该方法是 HttpServlet 类中的方法,可以在子类中重写这个方法。destroy方法的声明格式是:
public.destroy()
6.3 通过JSP页面访问servlet
1.通过表单向servlet提交数据
2.通过超链接访问servlet
6.4 共享变量
Sevet类是 HttpServlet的一个子类,在编写子类时就可以声明某些成员变量,那么,请求 servlet 的用户将共享该 servlet 的成员变量。
参考代码:
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_5_Servlet extends HttpServlet{
double sum=0,i=1,j=1; //被所有用户共享
int number=0; //被所有用户共享
public void init(ServletConfig config) throws ServletException{
super.init(config);
}
public synchronized void service(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("<html><body bgcolor=cyan>");
number++;
sum=sum+i/j;
j=j+2;
i = -i;
out.println("<h1>servlet:"+getServletName()+
"已经被请求了"+number+"次");
out.println("<br>现在PI的值是:");
out.println(4*sum);
out.println("</h1></body></html>");
}
}
jsp页面:
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=#ffccff>
<p style="font-family:宋体;font-size:36;color:blue">
<a href="computePI" >参与计算PI的值</a>
</p></body></HTML>
web.xml
6.5 doGet和doPost方法
HttpServlet 类除了 init、service destroy 方法外,该类还有两个很重要的方法:doGet 和 doPost,用来处理用户的请求并作出响应。当 Tomcat 服务器创建servlet 后,该 servlet 会调用 init 方法初始化自己,以后每当 Tomcat 服务器再接视频讲解受一个对该 servlet 请求时,就会产生一个新线程,并在这个线程中让该 servlet调用 service 方法。实际上 HttpServlet 类所给出的 service 方法的功能是检查HTTP 请求类型(get,post等),并在 service 方法中根据用户的请求方式,在 service方法中对应地再调用 doGet或 doPost方法。因此,在编写的 Servlet 类(HttpServlet类的一个子类时,也可以不重写 service 方法来响应用户,直接继承 service 方法即可。如果不重写service方法就需要在servlet类中重写doPost或doGet方法响应的请求。
参考代码:
servlet文件
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_6_Servlet extends HttpServlet{
public void init(ServletConfig config) throws ServletException{
super.init(config);
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("<html><body bgcolor=cyan>");
String s=request.getParameter("number");
String []a=s.split("[,,]+");
double sum = 0;
for(String item:a) {
if(item.length()>=1)
sum+=Double.parseDouble(item);
}
out.print("<h2>用户的请求方式是"+request.getMethod()+"<br>") ;
for(String item:a) {
if(item.length()>=1)
out.print(item+" ");
}
out.print("<br>的和是"+sum);
out.println("</h2></body></html>");
}
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println("<html><body bgcolor=yellow>");
String s=request.getParameter("number");
String []a=s.split("[,,]+");
double product = 1;
for(String item:a) {
if(item.length()>=1)
product*=Double.parseDouble(item);
}
out.print("<h2>用户的请求方式是"+request.getMethod()+"<br>") ;
for(String item:a) {
if(item.length()>=1)
out.print(item+" ");
}
out.print("<br>的乘积是"+product);
out.println("<h2></body></html>");
}
}
jsp页面
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#textStyle{
font-family:宋体;font-size:36;color:blue
}
</style>
<HTML><body bgcolor=#ffccff>
<form action="sumORproduct" id =textStyle method=post>
输入数字,用逗号分隔提交给servlet(post方式):
<br><input type=text id =textStyle name="number"/>
<input type=submit id =textStyle value="提交">
</form>
<form action="sumORproduct" id =textStyle method=get>
输入数字,用逗号分隔提交给servlet(get方式):
<br><input type=text id =textStyle name="number"/>
<input type=submit id =textStyle value="提交"/>
</form>
</body></HTML>
6.6 重定向与转发
重定向的功能是将用户从当前页面或servlet定向到另一个JSP页面或servlet。转发的功能是将用户对当前JSP页面或servlet的请求转发给另一个JSP页面或servlet.
1.sendRedorect方法
response.sendRedirect()会在客户端呈现跳转后的URL地址;(可以执行后面的语句eg:Request.jsp)这种称为客户端跳转,使用response.sendRedirect()方法将重定向的URL发送到客户端,浏览器再根据这个URL重新发送请求。用这个方法时,在浏览器地址栏上会看到新的请求资源的地址。并且这时的request和response都与第一次的不一样了,因为重新产生了response和request.
2.forward方法
使用< jsp:forward>完全是在服务器上进行。浏览器上的地址栏中的地址保持不变。(不能执行后面的语句eg:testjspforward.jsp所示)这种跳转称为服务器端的跳转。所以使用这个方法时没有产生新的request和response。因为request没有变,所以可以用request传递参数。
参考代码:
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#textStyle{
font-family:宋体;font-size:36;color:blue
}
</style>
<HTML><body bgcolor=#ffccff>
<p id=textStyle>
<form action="handleForward" id= textStyle method=post>
输入数字(用逗号空格或其他非数字字符分隔):<br>
<textArea name='digitData' id =textStyle rows=5 cols=30 >
</textArea>
<br><input type=submit id=textStyle name = submit value="提交(排序数字sort)"/>
<br><input type=submit id=textStyle name = submit value="提交(求数字代数和sum)"/>
</form>
</p></body></HTML>
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Example6_7_Servlet_Sum extends HttpServlet{
public void init(ServletConfig config) throws ServletException{
super.init(config);
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
String digitData = request.getParameter("digitData");
double sum = getPriceSum(digitData);
out.println("<html><body bgcolor=cyan>");
out.println("<h1>数字的代数和:"+sum);
out.println("</h1></body></html>");
}
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
doPost(request,response);
}
public double getPriceSum(String input){ // 定义方法
Pattern pattern; //模式对象。
Matcher matcher; //匹配对象。
String regex="-?[0-9][0-9]*[.]?[0-9]*" ;//匹配数字的正则表达式。
pattern = Pattern.compile(regex); //初试化模式对象。
matcher = pattern.matcher(input); //初始化匹配对象,用于检索input。
double sum = 0;
while(matcher.find()) {
String str = matcher.group();
sum += Double.parseDouble(str);
}
return sum;
}
}
package moon.sun;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Example6_7_Servlet extends HttpServlet{
public void init(ServletConfig config) throws ServletException{
super.init(config);
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
RequestDispatcher dispatcher = null; //负责转发的对象。
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String mess = request.getParameter("submit");
String digitData = request.getParameter("digitData");
if(digitData == null ||digitData.length()==0) {
response.sendRedirect("example6_7.jsp");//重定向到输入数据页面。
return;
}
if(mess.contains("sort")) {
dispatcher = request.getRequestDispatcher("sort");//转发给负责排序的servlet
dispatcher.forward(request,response);
}
else if(mess.contains("sum")){
dispatcher = request.getRequestDispatcher("sum");//转发给负责排序的servlet
dispatcher.forward(request,response);
}
}
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
doPost(request,response);
}
}
结果:
6.7 使用session
Http协议是用户与服务器之间一种请求与响应的通信协议,属于无状态协议.当用户在访问一个Web服务目录期间,Tomcat服务器为该用户分配一个session对象,页面会使用这个对象.具体格式为:
HttpSession session = request.getSession(true);
参考代码:
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor=#ffccff >
<% session.setAttribute("message","请您猜字母");
session.setAttribute("count","0");
char a[]=new char[26];
int m = 0;
for(char c='a';c<='z';c++) {
a[m] = c;
m++;
}
int randomIndex=(int)(Math.random()*a.length);
char ch=a[randomIndex]; //获取一个英文字母
session.setAttribute("savedLetter",new Character(ch));//将该字母放入session中
%>
<h3>访问或刷新该页面可以随机得到一个英文字母。
<br>单击超链接去猜出这个字母:<br>
<a href="example6_8_input.jsp">去猜字母</a>
</h3></body></HTML>
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#tom{
font-family:宋体;font-size:26;color:blue
}
</style>
<% String message=(String)session.getAttribute("message"); //获取会话中的信息
%>
<HTML><body bgcolor=#ffccff>
<table border=1>
<form action="guess" method=post>
<tr><td id =tom> 输入您的猜测(a~z之间的字母):</td>
<td><input type=text name=clientGuessLetter id =tom size=10/>
<input type=submit id =tom value="提交"/></td>
</tr><td id =tom> 提示信息:</td>
<td id =tom> <%= message%></td>
</form>
<form action="example6_8.jsp" method=post>
<tr><td id =tom>单击按钮重新开始: </td>
<td id =tom><input type=submit id =tom value="随机得到一个字母"/></td>
</tr>
</form>
</body></HTML>
结果:
总结
本章主要对java Servlet类进行了简单的说明,了解了Servlet是什么,怎么使用它,以及它的作用是什么等等.如何将Servlet与JSP页面紧密联系起来.