java Web学习总结(四) Servlet
1.Servlet的生命周期
2.HttpServlet
1.HttpServlet
i.我们所写的Servlet类都是继承自HttpServlet类,通常都是通过重写doGet()或doPost()方法来实现对用户请求的响应.
ii.HttpServlet类中的Service()方法实现了根据用户请求方式的不同,定义相应的doXXX()方法来处理用户请求.注意:我们自己实现的Servlet类中不要重写Service(),init()等方法.
2.HttpServletRequest
a.获取客户信息
方法 | 描述 |
---|---|
getRequestURL() | 返回客户端发出请求时的完整URL。 |
getRequestURI | 返回请求行中的资源名部分 |
getQueryString | 返回请求行中的参数部分 |
getRemoteAddr | 返回发出请求的客户机的IP地址 |
getRemoteHost | 返回发出请求的客户机的完整主机名 |
getRemotePort | 返回客户机所使用的网络端口号 |
getLocalAddr | 返回WEB服务器的IP地址 |
getLocalName | 返回WEB服务器的主机名 |
getMethod | 返回客户机请求方式 |
getServerPath() | 返回请求的文件的路径 |
b.获得客户机请求头
方法 | 描述 |
---|---|
getHeader(string name) | 返回指定头字段的值 |
getHeaders(String name) | 返回一个Enumeration集合对象(由指定名称的所有头字段组成) |
getHeaderNames() | 返回一个Enumeration集合对象(包含所有请求头字段) |
c.获得请求参数
方法 | 描述 |
---|---|
getParameter(string name) | 返回指定名称的参数值 |
getParameterValues(string name) | 返回指定名称的参数值集合(string[] 类型) |
getParameterNames() | 返回一个Enumeration集合对象(请求中所有参数名) |
getParameterMap() | 返回一个Map对象(包含请求中所有K-V对) |
3.HttpServletResponse
a.发送状态码
方法 | 描述 |
---|---|
setStatus(int status) | 设置响应状态码 |
sendError(int sc[, String message]) | 发送错误状态码[以及错误信息] |
b.发送响应消息头
方法 | 描述 |
---|---|
addHeader(String name, String value) | 添加响应头,value为int类型时可以调用addIntHeader() |
setHeader(String name, String value) | 设置响应头,value为int类型时可以调用setIntHeader() |
setConentLength(int len) | 设置响应消息实体内容大小 |
setContentType(String type) | 设置Servlet输出内容的MIME类型 |
setCharacterEncodeing(String charset) | 设置输出内容使用的字符编码,一般推荐"UTF-8" |
c.发送响应消息体
方法 | 描述 |
---|---|
getOutputStream() | 获取字节输出流对象ServletOutputStream类型 |
getWrite() | 获取字符输出流对象PrintWrite类型 |
注意: getOutputStream() 和 getWrite() 不能同时使用, 否则会发生异常
3.ServletConfig
在Servlet运行期间,会需要一些辅组信息,如编码等.该信息只对某一Servlet可见
1.在web.xml中配置一些参数信息
<servlet>
...
<servlet-class>ink.heat.servlet.TestServlet</servlet-class>
<init-param>
<param-naem>encoding</param-naem>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
2.在TestServlet中的doGet()中读取相关配置
ServletConfig config = this.getServletConfig();//获得ServletConfig对象
String param = config.getInitParameter("encoding");//获得"encoding"对应的参数值
4.ServletContext
每个Web应用有唯一的ServletContext对象,不仅封装了当前Web应用的所有信息,还实现了多个Servlet直接数据共享
1.获取Web应用程序初始化参数
1.在web.xml中初始化参数
<content-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</content-param>
2.在Servlet中获取
PrintWrite out = response.getWriter();
ServletContext context = this.getServletContext;//得到ServletContext对象
Enumeration<String> paramNames = context.getInitParameterNames();
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = context.getInitParameter(name);
out.print(name + ": " + value + "<br/>");
}
2.实现多个Servlet共享数据
方法 | 描述 |
---|---|
getAttributeNames() | 返回一个Enumeration 对象(包含所有存放在ServletContext中所有域属性名) |
getAttribute(String name) | 返回一个指定属性名的属性值(Object类型) |
removeAttribute(String name) | 删除一个指定属性名的属性 |
setAttribute(String name) | 设置Servlet的域属性 |
3.读取Web应用下的资源文件
方法 | 描述 |
---|---|
getResourcePaths(String path) | 返回一个set集合,集合中包含资源目录中子目录和文件的路径名称, path必须以"/"开始 |
getRealPath(String path) | 返回资源在服务器文件系统上的真实路径(绝对路径), path必须以"/"开始 |
getResource(String path) | 返回映射到某个资源文件的URL对象, path必须以"/"开始 |
getResourceAsStream(String name) | 返回映射到某个资源文件的InputStream对象, path必须以"/"开始 |
* 实例
1.创建一个资源文件"test.properties"在项目的src目录下
dbuname = root
dbupwd = root
注意 : src目录下创建的资源文件在Tomcat服务器启动时会被复制到项目的"WEB-INF/classes"目录下
2.在Servlet中读取
PrintWrite out = response.getWriter();
ServletContext context = this.getServletContext();
InputStream in= context.getResourceAsStream("/WEB-INF/classes/test.properties");
Properties pros = new Properties();
pros.load(in);
String dbuname = pros.getProperty("dbuname");
String dbupwd = pros.getProperty("dbupwd");
out.print(dbuname + ": " + dbupwd + "<br/>");
5.Servlet映射
1.多重映射的实现
-
方法一:在web.xml中为一个servlet配置多个
<servlet> <description></description> <display-name>LastAccessServlet</display-name> <servlet-name>LastAccessServlet</servlet-name> <servlet-class>ink.heat.servlet.LastAccessServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LastAccessServlet</servlet-name> <url-pattern>/las</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>LastAccessServlet</servlet-name> <url-pattern>/las1</url-pattern> </servlet-mapping>
-
方法二:在web.xml中一个元素下配置多个
<servlet-mapping> <servlet-name>LastAccessServlet</servlet-name> <url-pattern>/las</url-pattern> <url-pattern>/las1</url-pattern> </servlet-mapping>
2.映射路径中使用通配符
(1) “*.扩展名” 例如: " *.do"
(2) “/" 例如"/abc/”
注意: 两种通配符不能混合使用
6.[案例]实现用户登陆
登陆页面(login.jsp)用form表单提交用户信息
LoginServlet对应的url-pattern为: /login
CheckServlet对应的url-pattern为: /yzm
将标签中src属性设置为"yzm"可以让浏览器自动去访问CheckServlet,获取返回的验证码图片,其onclick事件是实现点击验证码图片实现局部刷新
用到了session技术可见后面章节,绘图所用swing知识可以暂时不去了解
1.login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="login" method="POST">
用户名:<input type="text" name="username"/><br/>
密码: <input type="password" name="password"/><br/>
验证码:<input type="text" name="checkcode"/>
<a href="#"><img id="checkImg" alt="验证码" src="yzm" οnclick="refresh()"></a><br/>
<input type="submit" value="login"/>
</form>
<script type="text/javascript">
var checkImg = document.getElementById("checkImg");
checkImg.onclick = function() {
this.src = "yzm?r=" + Math.random();
}
</script>
</body>
</html>
2.LoginServlet
package ink.heat.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LoginServlet
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到用户名,密码,用户输入的验证码以及实际验证码
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String username = (String)request.getParameter("username");
String password = (String)request.getParameter("password");
String checkcode = (String)request.getParameter("checkcode");
String realCheckCode = (String)request.getSession().getAttribute("check_code");
if ("zs".equals(username) && "123".equals(password)) {
if (!realCheckCode.equals(checkcode)) {
response.getWriter().print("验证码错误[" + checkcode + "," + realCheckCode + "]");
} else {
response.getWriter().print("验证正确!");
}
} else {
response.getWriter().print("用户名或密码错误[" + username + "," + password + "]");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
3.CheckServlet
package ink.heat.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
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;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class CheckServlet
*/
public class CheckServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static int WIDTH = 60;
private static int HEIGHT = 20;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
response.setContentType("image/jpeg");
ServletOutputStream sos = response.getOutputStream();
//设置浏览器不要缓存此图片
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
//创建内存图像并获得其图形上下文
BufferedImage image =
new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
//产生随机的认证码
char[] rands = generateCheckCode();
//产生图像
drawBackground(g);
drawRands(g, rands);
//结束绘制过程
g.dispose();
//将图像输出到客户端
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "JPEG", bos);
byte[] buf = bos.toByteArray();
response.setContentLength(buf.length);
sos.write(buf);
bos.close();
sos.close();
//将当前验证码存入Session中
session.setAttribute("check_code", new String(rands));
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
private char[] generateCheckCode() {
//定义验证码的字符表
String chars = "0123456789abcdefghijklmnopqrstuvwxyz";
char[] rands = new char[4];
for (int i = 0; i < 4; i++) {
int rand = (int)(Math.random() * 36);
rands[i] = chars.charAt(rand);
}
return rands;
}
private void drawRands(Graphics g, char[] rands) {
g.setColor(Color.BLACK);
g.setFont(new Font(null, Font.ITALIC|Font.BOLD, 18));
//在不同高度上输出验证码的每个字符
g.drawString("" + rands[0], 1, 17);
g.drawString("" + rands[1], 16, 16);
g.drawString("" + rands[2], 31, 18);
g.drawString("" + rands[3], 46, 16);
System.out.println(rands);
}
private void drawBackground(Graphics g) {
//画背景
g.setColor(new Color(0xDCDCDC));
g.fillRect(0, 0, WIDTH, HEIGHT);
//随机产生120个干扰
for (int i = 0; i < 120; i++) {
int x = (int)(Math.random() * WIDTH);
int y = (int)(Math.random() * HEIGHT);
int red = (int)(Math.random() * 255);
int green = (int)(Math.random() * 255);
int blue = (int)(Math.random() * 255);
g.setColor(new Color(red, green, blue));
g.drawOval(x, y, 1, 0);
}
}
}
4.web.xml部分
<servlet>
<description></description>
<display-name>CheckServlet</display-name>
<servlet-name>CheckServlet</servlet-name>
<servlet-class>ink.heat.servlet.CheckServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CheckServlet</servlet-name>
<url-pattern>/yzm</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>LoginServlet</display-name>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>ink.heat.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>