Servlet(Server Applet),全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。
此程序在服务器上运行用来处理Web客户端请求,并作出响应。
其实质是用来处理客户端的Http请求并响应。
Servlet请求的处理过程:
- 客户端提交一个HTTP请求(POST,GET)
- 容器(Tomcat)接收到请求后,截取你的请求路径
- 容器把截取的请求路径到当前Web程序的web.xml中进行匹配,看看有没有Servlet处理这个路径
- 如果有,容器创建或查找到一个处理这个路径请求的Servlet实例
- 容器启动一个线程
- 容器封装两个对象:HttpServletRequest 代表请求对象,客户端提交的数据都存放在这里面; HttpServletResponse 代表响应对象,服务器要返回给客户端的数据放到这里
- 调用相应的处理方法(doGet(),doPost()),处理完毕,向客户返回响应结果
- 结束这个线程
web容器调用Servlet处理请求过程
Servlet的生命周期全过程
doGet()和doPost()要注意线程安全问题
...
public class SafeServlet extends HttpServlet{
private static final long serialVersionUID = -612418621051462414L;
private int count;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
...
//访问成员变量,一定要加一个锁
synchronized(this.getClass()){
out.println("本Servlet已经被访问了"+(++count)+"次");
}
...
}
}
HttpServletRequest 对象
备注:解决win7以上系统Java只获取IPv6的问题
HttpServletResponse 对象
示例一:注册功能的实现
1,编写register.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>注册网页</title>
</head>
<body>
<h3 style="margin-left: 20px;">注册网页</h3>
<form action="register.do" method="post">
<table border="1" style="width:600px;">
<tr>
<td align="center">用户名</td>
<td><input type="text" name="lname"/></td>
</tr>
<tr>
<td align="center">密码</td>
<td><input type="password" name="pwd"/></td>
</tr>
<tr>
<td align="center">性别</td>
<td>
<input type="radio" name="gender" value="m" checked="checked"/>男
<input type="radio" name="gender" value="f"/>女
<input type="radio" name="gender" value="o"/>保密
</td>
</tr>
<tr>
<td align="center">爱好</td>
<td>
<input type="checkbox" name="hobby" value="sp"/>运动
<input type="checkbox" name="hobby" value="s"/>睡觉
<input type="checkbox" name="hobby" value="inte"/>上网
<input type="checkbox" name="hobby" value="shop"/>逛街
</td>
</tr>
<tr>
<td align="center">学历</td>
<td>
<select name="edu">
<optgroup label="初等教育">
<option value="1">小学</option>
<option value="2">初中</option>
<option value="3">高中</option>
</optgroup>
<optgroup label="中等教育">
<option value="4">大专</option>
<option value="5">本科</option>
</optgroup>
<optgroup label="高等教育">
<option value="6">硕士</option>
<option value="7">博士</option>
<option value="8">博士后</option>
</optgroup>
</select>
</td>
</tr>
<tr>
<td colspan="2" align="center" ><input type="submit" value="注册"/></td>
</tr>
</table>
</form>
</body>
</html>
2,处理这个“注册”按钮的http请求
package com.jackie.web.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RegisterServlet extends HttpServlet{
private static final long serialVersionUID = -8882961568690672286L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String lname = req.getParameter("lname");
String pwd = req.getParameter("pwd");
String gender = req.getParameter("gender");
String [] hobbies = req.getParameterValues("hobby");
String edu = req.getParameter("edu");
//实际中是要插入数据库中
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset='utf-8'/> <title>响应网页的标题</title>");
out.println("</head>");
out.println("<body>");
out.println("用户名:"+ lname +"<br>");
out.println("密码:"+ pwd +"<br>");
out.println("性别:"+ gender +"<br>");
out.println("爱好:"+ Arrays.toString(hobbies) +"<br>");
out.println("学历:"+ edu +"<br>");
out.println("</body>");
out.println("</html>");
}
}
3,在web.xml中注册
...
<servlet>
<servlet-name>register</servlet-name>
<servlet-class>com.jackie.web.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>register</servlet-name>
<url-pattern>/register.do</url-pattern>
</servlet-mapping>
...
示例二:实现登录和图片验证码生成功能
1,编写login.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录网页</title>
</head>
<body>
<h3>登录网页的提交</h3>
<form action="login" method="get"><!-- 当前目录下的相对路径 -->
<table border="1" style="width:600px;">
<tr>
<td>用户名</td>
<td><input type="text" name="lname"/></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="pwd"/></td>
</tr>
<tr>
<td>验证码</td>
<td><input type="text" name="vc" size="6"/> <img id="vc_img" src="vc.png" style="width:80px;height:22px ;cursor: pointer" title="看不清?点击图片换一张"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
<script type="text/javascript">
var img = document.getElementById("vc_img");
img.onclick = function (){
img.src = 'vc.png?d=' + new Date().getTime();
};
</script>
</body>
</html>
2,处理这个“登录”按钮的http请求
package com.jackie.web.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;
/**
* JavaWeb中的Servlet要继承自 javax.servlet.http.HttpServlet类</br>
* 重写doGet()和doPost()方法。
* @author Administrator
*
*/
public class LoginServlet extends HttpServlet{
private static final long serialVersionUID = -612418621051462414L;
/**
* @param req 代表客户端的请求对象
* @param resp 代表服务器的响应对象
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//step1:获取客户端提交的请求参数
req.setCharacterEncoding("UTF-8");
String lname = req.getParameter("lname");
String pwd = req.getParameter("pwd");
//step2:处理业务逻辑
//单独写一个UseDao类
//step3:给客户端返回响应
resp.setContentType("text/html;charset=UTF-8");//设置响应内容的类型
PrintWriter out = resp.getWriter();//从响应对象中获取一个字符输出流》用于向客户端输出响应数据
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset='utf-8'/> <title>响应网页的标题</title>");
out.println("</head>");
out.println("<body>");
if (lname.equals("admin") && pwd.equals("123456")){
out.println("欢迎!");
}else{
out.println("请重新登录!");
}
out.println("</body>");
out.println("</html>");
}
}
2,处理这个“验证码”按钮的http请求
package com.jackie.web.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class VerifyCodeServlet
*/
public class ValifyCodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
generic(out);
}
public static String [] src = {"A","B","C","D","E","F","G","H","I","J","K",
"L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
"0","1","2","3","4","5","6","7","8","9"};
public static Random random = new Random();
public static void generic(OutputStream os) throws IOException {
BufferedImage bi = new BufferedImage(90, 40, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
// 画背景
//Image bg = ImageIO.read(new File("xxx.png"));
//g.drawImage(bg,0,0,null);
g.setColor(new Color(255, 201, 14));
g.fillRect(0, 0, 90, 40);
// 画边框
g.setColor(Color.BLACK);
g.drawRect(0, 0, 90 - 1, 40 - 1);
// 画文字
g.setColor(Color.WHITE);
g.setFont(new Font("Consolas", Font.BOLD|Font.ITALIC, 28));
for (int i = 0 ; i < 4 ; i ++){
int index = random.nextInt(src.length);
g.drawString(src[index], 10+(i*19), 27);
}
ImageIO.write(bi, "png", os);
}
}
3,在web.xml中注册
<?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">
<!-- 注册一个Servlet实例 -->
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.jackie.web.servlet.LoginServlet</servlet-class>
</servlet>
<!-- 指定这个Servlet要处理的URL模式 -->
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>ValifyCodeServlet</display-name>
<servlet-name>ValifyCodeServlet</servlet-name>
<servlet-class>com.jackie.web.servlet.ValifyCodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ValifyCodeServlet</servlet-name>
<url-pattern>/vc.png</url-pattern>
</servlet-mapping>
</web-app>