java Web学习总结(四) Servlet

java Web学习总结(四) Servlet

1.Servlet的生命周期

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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值