Java进阶-request&response (十一)

文章目录

  • (一)response
  • 一、案例1:记录网站的登录成功人数
    • 1.1、需求说明
    • 1.2、知识点-ServletContext
    • 1.3、response
      • 1.3.1、response对象操作响应行
      • 1.3.2、response对象操作响应头
      • 1.3.3、response对象操作响应体
    • 1.4、资源跳转-重定向
    • 1.5、网站的登录成功人数
  • 二、案例2:读取WEB工程下的资源文件
    • 2.1、需求说明
    • 2.2、案例代码实现-JavaSE
  • 三、案例3:文件下载
    • 3.1、需求说明
    • 3.2、案例代码实现
  • 四、案例4:点击切换验证码
    • 4.1、需求说明
    • 4.2、案例原型准备
      • 4.2.1 生成图片验证码工具:(无需手写,直接使用)
    • 4.3、案例代码实现
  • (二) request
  • 一、案例一:用户注册
    • 1.1、流程分析
    • 1.2、代码实现
    • 1.3、代码优化
      • 1.3.1、问题:每一个表单参数就要写一个getParameter(),不利于开发
      • 1.3.2、问题:将生日改为日期类型
      • 1.3.3、问题:中文乱码
    • 1.4、request对象
      • 1.4.1、request继承树
      • 1.4.2、request操作请求体
      • 1.4.3、request和response的执行流程
  • 二、案例二:用户注册信息回显前端
    • 2.1、流程分析
    • 2.2、代码实现(重定向)
    • 2.3、代码优化(转发)完整代码
      • 2.3.1、问题:不同用户间回显信息冲突问题
    • 2.4、讲解:请求转发和重定向的区别

(一)response

一、案例1:记录网站的登录成功人数

1.1、需求说明

Java进阶-request&response (十一)_第1张图片

登录成功后,5秒后跳转到某个页面,在页面中显示您是第x位登录成功的用户.

1.2、知识点-ServletContext

是什么? 是一个项目中独一无二的身份证对象
可以存取数据, 范围: 在整个WEB工程都可以获取到

生命周期

何时创建: 服务器启动
何时销毁: 服务器正常关闭

如何获取:

作用:

1.获取web.xml文件中的配置信息
2.域对象

ServletContext对象

域对象:在域作用范围内进行数据共享。就相当于map集合

方法名 描述
setAttribute(String name,Object object) 向ServletContext中存数据 相当于 map.put(key , value)
getAttribute(String name) 从ServletContext中取数据 相当于map.get(key)
removeAttribute(name) 从ServletContext中移除数据 相当于map.remove(key)

(1)创建案例 servlet

(2)web.xml文件内容体为:

添加部分:
Java进阶-request&response (十一)_第2张图片

完整代码:


<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">
  <display-name>servletdisplay-name>
  <welcome-file-list>
    <welcome-file>index.htmlwelcome-file>
    <welcome-file>index.htmwelcome-file>
    <welcome-file>index.jspwelcome-file>
    <welcome-file>default.htmlwelcome-file>
    <welcome-file>default.htmwelcome-file>
    <welcome-file>default.jspwelcome-file>
  welcome-file-list>
  <context-param>
    <param-name>encodingparam-name>
    <param-value>UTF-8param-value>
  context-param>
  <servlet>
    <description>description>
    <display-name>DemoServlet2display-name>
    <servlet-name>DemoServlet2servlet-name>
    <servlet-class>com.zql.DemoServlet2servlet-class>
  servlet>
  <servlet-mapping>
    <servlet-name>DemoServlet2servlet-name>
    <url-pattern>/demo2url-pattern>
  servlet-mapping>
web-app>

(3)创建类DemoServlet1

package com.zql;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/demo1")
public class DemoServlet1 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//使用servletContext获得对象	
		ServletContext context = this.getServletContext();
		
		ServletContext context2 = request.getServletContext();
		
		System.out.println(context == context2);
		//获取web.xml参数值
		String encoding = context.getInitParameter("encoding");
		
		System.out.println(encoding);
		//使用设置值
		context.setAttribute("name", "Daniel");
		
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doGet(request, response);
	}
}

(4)创建类DemoServlet2

package com.zql;

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 DemoServlet2 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//使用servletContext取对象
		ServletContext context = this.getServletContext();
		
		String name = (String) context.getAttribute("name");
		
		System.out.println(name);
		
		//使用移除数据
		context.removeAttribute("name");
		//重新查看是否有数据
		String name1= (String) context.getAttribute("name");
		
		System.out.println("移除后的值为"+name1);
	}

	/**
	 * @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);
	}
}

显示为:

1.访问:http://localhost:8080/servlet2/demo1
Java进阶-request&response (十一)_第3张图片
2.访问:http://localhost:8080/servlet2/demo2

Java进阶-request&response (十一)_第4张图片

1.3、response

在Servlet API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。

在这里插入图片描述

ServletResponse: 普通响应接口 , 不能处理HTTP协议
HttpServletResponse: 专门HTTP协议的响应接口

Response对象封装了响应行、头、体三部分信息,我们可以通过调用response对象的方法,来轻松控制服务器向浏览器写响应信息

1.3.1、response对象操作响应行

状态码:

200:响应成功
404:路径找不到
500:服务器内部代码问题
302:重定向
304:缓存

setStatus(int status);

该方法用于设置HTTP响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而HTTP版本由服务器确定,因此,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。
若未设置状态码,且服务器运行正常,Web服务器会默认产生一个状态码为200的状态行。

response.setStatus(444);

Java进阶-request&response (十一)_第5张图片

1.3.2、response对象操作响应头

当Servlet向客户端发送响应消息时,由于HTTP协议的响应头字段有很多种,为此,在HttpServletResponse接口中,定义了一系列设置HTTP响应头字段的方法,如表4-1所示。

表1-1设置响应消息头字段的方法

方法声明

Java进阶-request&response (十一)_第6张图片

方法声明 功能描述
void addHeader(String name, String value)
//IDEA自定义响应头 response.addHeader("name","Daniel");
//浏览器F12查看
Response  Header  View source
Content-Length:0
Date:Mon,20 Jun 2022 06:57:37 GMT
name:Daniel
这两个方法都是用来设置HTTP协议的响应头字段,其中,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。不同的是,addHeader()方法可以增加同名的响应头字段,而setHeader()方法则会覆盖同名的头字段
void setHeader(String name, String value)
void setCharacterEncoding(String charset) 该方法用于设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码部分。
void setContentType(String type) 该方法用于设置Servlet输出内容的MIME类型,对于HTTP协议来说,就是设置Content-Type响应头字段的值。例如,如果发送到客户端的内容是jpeg格式的图像数据,就需要将响应头字段的类型设置为“image/jpeg”。需要注意的是,如果响应的内容为文本,setContentType()方法的还可以设置字符编码,如:text/html;charset=UTF-8
void addIntHeader(String name,int value) 这两个方法专门用于设置包含整数值的响应头。避免了使用addHeader()与setHeader()方法时,需要将int类型的设置值转换为String类型的麻烦
void setIntHeader(String name,int value)
void setContentLength(int len) 该方法用于设置响应消息的实体内容的大小,单位为字节。对于HTTP协议来说,这个方法就是设置Content-Length响应头字段的值 无需手动设置,由服务器自行设置

1.3.3、response对象操作响应体

响应体信息无限,所以一般用来传递大量数据。

getOutputStream()

向响应体输出二进制字节流信息。

getWriter()

向响应体输出字符流信息。

注意事项:

1.一山不容二虎 (这个流不能同时使用) 除非你用了 if else判断
2.中文乱码问题

Java进阶-request&response (十一)_第7张图片
添加代码:

//response.setCharacterEncoding("utf-8");//无法确定不同用户使用的浏览器默认编码
		response.setContentType("text/html;charset=utf-8");//乱码解决方案
if(false) {
			ServletOutputStream out = response.getOutputStream(); 
			
			out.write("我是正确的".getBytes()); //第一种页面显示
		}else {
			
			response.getWriter().write("我是错误的");//第二种页面显示
			//也可以写标签js  中文会出现乱码
		}

1.4、资源跳转-重定向

资源跳转有两种:

1.重定向
2.转发

重定向

Java进阶-request&response (十一)_第8张图片

1.立即重定向

System.out.println("demo4开始执行了");
		
response.sendRedirect("/servlet2/index.html");

index.html

DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>
	<h1>
		重定向过来了
	h1>
body>
html>

Java进阶-request&response (十一)_第9张图片
2.延迟重定向:

response.setContentType("text/html;charset=utf-8");
		System.out.println("demo4开始执行了");
		
		//response.sendRedirect("/servlet2/index.html");
		
		response.getWriter().write("

5秒后会跳转到index.html页面

"
); response.setHeader("refresh", "5;url=/servlet2/index.html");

1.5、网站的登录成功人数

(1)流程分析
Java进阶-request&response (十一)_第10张图片
(2)案例代码实现(见4.5)

(3)改动部分:

if(user != null) {
			
			resp.getWriter().write("

登录成功即将跳转到index页面

"
); count++; this.getServletContext().setAttribute("count", count); resp.setHeader("refresh", "5;url=/login/index"); }else { resp.getWriter().write("

登录失败

"
); }

(4)完整代码:

package com.zql.servlet;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zql.pojo.User;
import com.zql.service.UserService;


@WebServlet("/login")
public class UserServlet extends HttpServlet{
	private int count = 0;
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		resp.setContentType("text/html;charset=utf-8");
		try {
			
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		
		System.out.println(username+"-----------"+password);
		
		UserService service = new UserService();
		
		User user = service.login(username,password);
		
		if(user != null) {
			
			resp.getWriter().write("

登录成功即将跳转到index页面

"
); count++; this.getServletContext().setAttribute("count", count); resp.setHeader("refresh", "5;url=/login/index"); }else { resp.getWriter().write("

登录失败

"
); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

(5)额外建类(servlet包下Index)

package com.zql.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/index")
public class Index extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		
		Object count = this.getServletContext().getAttribute("count");
		
		response.getWriter().write("您是第"+count+"登录成功的用户");
	
	}

	/**
	 * @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);
	}

}

最终登录成功显示:
Java进阶-request&response (十一)_第11张图片

二、案例2:读取WEB工程下的资源文件

2.1、需求说明

在web项目中分别在不同地方创建4个txt文件,分别取读取里边的内容
Java进阶-request&response (十一)_第12张图片

package com.zql;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;

public class Demo {
	
	public static void main(String[] args) throws Exception {
		
		getFile("src/a.txt");
		getFile("webContent/WEB-INF/b.txt");
		getFile("webContent/c.txt");
		getFile("d.txt");
	}
	
	public static void getFile(String file) throws Exception {
		
		//String path = "";
		
		//File file = new File(path);
		
		BufferedReader bfd = new BufferedReader(new FileReader(file));
		
		System.out.println(bfd.readLine());
		
	}

}

2.2、案例代码实现-JavaSE

Java进阶-request&response (十一)_第13张图片

package com.zql;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class Demo12 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		try {
			//getFile("");
			
			String path = this.getServletContext().getRealPath("/");
			
			System.out.println(path);
			
			getFile(path+"WEB-INF/classes/a.txt");
			
			getFile(path+"WEB-INF/b.txt");
			
			getFile(path+"c.txt");
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
		public static void getFile(String file) throws Exception {
		
		BufferedReader bfd = new BufferedReader(new FileReader(file));
		
		System.out.println(bfd.readLine());
		
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doGet(request, response);
	}

}

结果显示为:
Java进阶-request&response (十一)_第14张图片

三、案例3:文件下载

强制下载响应头设置
// 必须写在getOutputStream()之前 正文-配置 filename是下载名
//下载名会直接显示在下载的窗口中

引用代码:

response.setHeader("Content-Disposition", "attachment;filename="+filename);

3.1、需求说明

分别使用超链接和自定义Servlet程序,进行网站资源的下载。

超链接下载:

直接在网页看到图面和文档中内容, 是在浏览器上进行显示的

自定义下载:

我们要把它下载到本地磁盘上

3.2、案例代码实现

案例结构:
Java进阶-request&response (十一)_第15张图片

(1)在WebContent下面创建down内含图片,文本,压缩包文件(随便找些);

(2)创建down.html

DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body>


		<a href="/servlet3/down/1.jpg">1.jpga>
		<a href="/servlet3/down/2.zip">2.zipa>
		<a href="/servlet3/down/3.txt">3.txta>
		
		<hr/>
	
		<a href="/servlet3/download?filename=1.jpg">1.jpga>

body>
html>

(3)创建下载类

package com.zql;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/download")
public class DownLoad extends HttpServlet {
	
	@SuppressWarnings("resource")
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String path = this.getServletContext().getRealPath("/down/");
		
		String filename = request.getParameter("filename");
		
		
		//System.out.println(path+file);
		response.setHeader("Content-Disposition", "attachment;file="+filename);
		
		FileInputStream fis = new FileInputStream(new File(path+filename));
		
		OutputStream os = response.getOutputStream();
		
		int len = 0;
		
		byte[] obj = new byte[1024];
		
		
		while((len = fis.read())!= -1 ) {
			
			os.write(obj, 0, len);
		}
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doGet(request, response);
	}

}

(4) 访问:http://localhost:8080/servlet3/down.html

Java进阶-request&response (十一)_第16张图片

四、案例4:点击切换验证码

4.1、需求说明

在访问登录页面时,需要生成验证码。从而防止用户使用程序恶意操作。

Java进阶-request&response (十一)_第17张图片
验证码: 本质就是一张图片

作用: 防止用户进行恶意操作 (登录 / 注册) 用户输入验证码的时间 也就给服务器进行喘气的时间

验证码的难易程度: 取决于网站的流量多少

4.2、案例原型准备

4.2.1 生成图片验证码工具:(无需手写,直接使用)

package com.zql.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/vs")
public class VerifyCodeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	//生成图片
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		
		//1 高和宽
		int height = 30;
		int width = 60;
		String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
		Random random = new Random();
		
		
		//2 创建一个图片
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		
		//3 获得画板
		Graphics g = image.getGraphics();
		//4 填充一个矩形
		// * 设置颜色
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, width, height);
		
		g.setColor(Color.WHITE);
		g.fillRect(1, 1, width-2, height-2);
		// * 设置字体
		g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 25));
		
		
		//5 写随机字
		for(int i = 0 ; i < 4 ; i ++){
			// 设置颜色--随机数
			g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
			
			// 获得随机字
			int index = random.nextInt(data.length());
			String str = data.substring(index, index + 1);
			
			// 写入
			g.drawString(str, width/6 * (i + 1), 20);
			
		}
		
		//6 干扰线
		for(int i = 0 ; i < 3 ; i ++){
			// 设置颜色--随机数
			g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
			// 随机绘制先
			g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width),random.nextInt(height));
			// 随机点
			g.drawOval(random.nextInt(width), random.nextInt(height), 2, 2);
		}
		
		
		//end 将图片响应给浏览器
		ImageIO.write(image, "jpg", response.getOutputStream());
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		doGet(request, response);
	}

}

4.3、案例代码实现

(1) 使用之前写好的成功登录页面套件见4.5
(2)添加 (4.2.1) 代码,位置如下:
Java进阶-request&response (十一)_第18张图片
(3)找到对应验证码位置(F12找)

并且添加如下:
Java进阶-request&response (十一)_第19张图片

 <img src="/login/vs"  onclick="changeImg(this)"/>

(4)编写js


<script type="text/javascript">
		
		function changeImg(obj) {
			//alert(11);
			
			obj.src="/login/vs?time="+new Date().getTime();
		}

</script>

(5)完整login.html

doctype html>
<html>
<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>会员登录title>
		<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
		<script src="js/jquery-1.11.3.min.js" type="text/javascript">script>
		<script src="js/bootstrap.min.js" type="text/javascript">script>

<link rel="stylesheet" href="css/style.css" type="text/css"/>

<script type="text/javascript">
		
		function changeImg(obj) {
			//alert(11);
			
			obj.src="/login/vs?time="+new Date().getTime();
		}

script>

<style>
  body{
   margin-top:20px;
   margin:0 auto;
 }
 .carousel-inner .item img{
	 width:100%;
	 height:300px;
 }
 .container .row div{ 
	 /* position:relative;
	 float:left; */
 }
 
font {
    color: #666;
    font-size: 22px;
    font-weight: normal;
    padding-right:17px;
}
 style>
head>
<body>

			<div class="container-fluid">
				<div class="col-md-4">
					<img src="img/logo.png" />
				div>
				<div class="col-md-5">
					<img src="img/header.png" />
				div>
				<div class="col-md-3" style="padding-top:20px">
					<ol class="list-inline">
						<li><a href="login.htm">登录a>li>
						<li><a href="register.htm">注册a>li>
						<li><a href="cart.htm">购物车a>li>
					ol>
				div>
			div>
			
			<div class="container-fluid">
				<nav class="navbar navbar-inverse">
					<div class="container-fluid">
						
						<div class="navbar-header">
							<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
								<span class="sr-only">Toggle navigationspan>
								<span class="icon-bar">span>
								<span class="icon-bar">span>
								<span class="icon-bar">span>
							button>
							<a class="navbar-brand" href="#">首页a>
						div>

						
						<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
							<ul class="nav navbar-nav">
								<li class="active"><a href="#">手机数码<span class="sr-only">(current)span>a>li>
								<li><a href="#">电脑办公a>li>
								<li><a href="#">电脑办公a>li>
								<li><a href="#">电脑办公a>li>
							ul>
							<form class="navbar-form navbar-right" role="search">
								<div class="form-group">
									<input type="text" class="form-control" placeholder="Search">
								div>
								<button type="submit" class="btn btn-default">Submitbutton>
							form>

						div>
						
					div>
					
				nav>
			div>


<div class="container"  style="width:100%;height:460px;background:#FF2C4C url('img/loginbg.jpg') no-repeat;">
<div class="row"> 
	<div class="col-md-7">
		
	div>
	
	<div class="col-md-5">
				<div style="width:440px;border:1px solid #E7E7E7;padding:20px 0 20px 30px;border-radius:5px;margin-top:60px;background:#fff;">
				<font>会员登录font>USER LOGIN

				<div> div>
<form class="form-horizontal" action="/login/login" method="post">
  
 <div class="form-group">
    <label for="username" class="col-sm-2 control-label">用户名label>
    <div class="col-sm-6">
      <input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名">
    div>
  div>
   <div class="form-group">
    <label for="inputPassword3" class="col-sm-2 control-label">密码label>
    <div class="col-sm-6">
      <input type="password" class="form-control" name="password" id="inputPassword3" placeholder="请输入密码">
    div>
  div>
   <div class="form-group">
        <label for="inputPassword3" class="col-sm-2 control-label">验证码label>
    <div class="col-sm-3">
      <input type="text" class="form-control" id="inputPassword3" placeholder="请输入验证码">
    div>
    <div class="col-sm-3">
     
       <img src="/login/vs"  onclick="changeImg(this)"/>
    div>
    
  div>
   <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <div class="checkbox">
        <label>
          <input type="checkbox"> 自动登录
        label>     
        <label>
          <input type="checkbox"> 记住用户名
        label>
      div>
    div>
  div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
    <input type="submit"  width="100" value="登录" name="submit" border="0"
    style="background: url('img/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0);
    height:35px;width:100px;color:white;">
    div>
  div>
form>
div>			
	div>
div>
div>	

	<div style="margin-top:50px;">
			<img src="img/footer.jpg" width="100%" height="78" alt="我们的优势" title="我们的优势" />
		div>

		<div style="text-align: center;margin-top: 5px;">
			<ul class="list-inline">
				<li><a>关于我们a>li>
				<li><a>联系我们a>li>
				<li><a>招贤纳士a>li>
				<li><a>法律声明a>li>
				<li><a>友情链接a>li>
				<li><a target="_blank">支付方式a>li>
				<li><a target="_blank">配送方式a>li>
				<li><a>服务声明a>li>
				<li><a>广告声明a>li>
			ul>
		div>
		<div style="text-align: center;margin-top: 5px;margin-bottom:20px;">
			Copyright © 2022-2099 Daniel version
		div>
body>html>

最终效果显示(点击可变换):
Java进阶-request&response (十一)_第20张图片

(二) request

一、案例一:用户注册

1.1、流程分析

Java进阶-request&response (十一)_第21张图片

1.2、代码实现

所需资源下载

(1) 导入sql:

CREATE DATABASE register;
USE register;
CREATE TABLE USER(
 uid VARCHAR(32) PRIMARY KEY,
 username VARCHAR(100) UNIQUE,
 PASSWORD VARCHAR(100),
 email VARCHAR(100),
 NAME VARCHAR(100),
 sex VARCHAR(10),
 birthday TIMESTAMP
);
INSERT INTO USER VALUES ('00a','Daniel','123','[email protected]','管理员','man','2022-01-01 05:50:50');

(2)案例结构:
Java进阶-request&response (十一)_第22张图片

(3)静态资源

Java进阶-request&response (十一)_第23张图片

(4)jar包

Java进阶-request&response (十一)_第24张图片

(5)工具类和xml

Java进阶-request&response (十一)_第25张图片

(6) register.html 代码添加对应name 和form标签方式

doctype html>
<html>
	<head>head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>会员登录title>
		<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
		<script src="js/jquery-1.11.3.min.js" type="text/javascript">script>
		<script src="js/bootstrap.min.js" type="text/javascript">script>

<link rel="stylesheet" href="css/style.css" type="text/css"/>

<style>
  body{
   margin-top:20px;
   margin:0 auto;
 }
 .carousel-inner .item img{
	 width:100%;
	 height:300px;
 }
 .container .row div{ 
	 /* position:relative;
	 float:left; */
 }
 
font {
    color: #3164af;
    font-size: 18px;
    font-weight: normal;
    padding: 0 10px;
}
 style>
head>
<body>
			
			<div class="container-fluid">
				<div class="col-md-4">
					<img src="img/logo.png" />
				div>
				<div class="col-md-5">
					<img src="img/header.png" />
				div>
				<div class="col-md-3" style="padding-top:20px">
					<ol class="list-inline">
						<li><a href="login.htm">登录a>li>
						<li><a href="register.htm">注册a>li>
						<li><a href="cart.htm">购物车a>li>
					ol>
				div>
			div>
			
			<div class="container-fluid">
				<nav class="navbar navbar-inverse">
					<div class="container-fluid">
						
						<div class="navbar-header">
							<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
								<span class="sr-only">Toggle navigationspan>
								<span class="icon-bar">span>
								<span class="icon-bar">span>
								<span class="icon-bar">span>
							button>
							<a class="navbar-brand" href="#">首页a>
						div>

						
						<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
							<ul class="nav navbar-nav">
								<li class="active"><a href="#">手机数码<span class="sr-only">(current)span>a>li>
								<li><a href="#">电脑办公a>li>
								<li><a href="#">电脑办公a>li>
								<li><a href="#">电脑办公a>li>
							ul>
							<form class="navbar-form navbar-right" role="search">
								<div class="form-group">
									<input type="text" class="form-control" placeholder="Search">
								div>
								<button type="submit" class="btn btn-default">Submitbutton>
							form>

						div>
						
					div>
					
				nav>
			div>
<div class="container" style="width:100%;background:url('image/regist_bg.jpg');">
<div class="row"> 
	<div class="col-md-2">div>
	<div class="col-md-8" style="background:#fff;padding:40px 80px;margin:30px;border:7px solid #ccc;">
		<font>会员注册font>USER REGISTER
		<form class="form-horizontal" style="margin-top:5px;" action="/register/register" method="post">
			 <div class="form-group">
			    <label for="username" class="col-sm-2 control-label">用户名label>
			    <div class="col-sm-6">
			      <input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名">
			    div>
			  div>
			   <div class="form-group">
			    <label for="inputPassword3" class="col-sm-2 control-label">密码label>
			    <div class="col-sm-6">
			      <input type="password" class="form-control" id="inputPassword3" name="password" placeholder="请输入密码">
			    div>
			  div>
			   <div class="form-group">
			    <label for="confirmpwd" class="col-sm-2 control-label">确认密码label>
			    <div class="col-sm-6">
			      <input type="password" class="form-control" id="confirmpwd" placeholder="请输入确认密码">
			    div>
			  div>
			  <div class="form-group">
			    <label for="inputEmail3" class="col-sm-2 control-label">Emaillabel>
			    <div class="col-sm-6">
			      <input type="email" class="form-control" id="inputEmail3" name="email" placeholder="Email">
			    div>
			  div>
			 <div class="form-group">
			    <label for="usercaption" class="col-sm-2 control-label">姓名label>
			    <div class="col-sm-6">
			      <input type="text" class="form-control" id="usercaption" name="name" placeholder="请输入姓名">
			    div>
			  div>
			  <div class="form-group opt">  
			  <label for="inlineRadio1" class="col-sm-2 control-label">性别label>  
			  <div class="col-sm-6">
			    <label class="radio-inline">
			  <input type="radio" name="sex" id="inlineRadio1" value="man">label>
			<label class="radio-inline">
			  <input type="radio" name="sex" id="inlineRadio2" value="woman">label>
			div>
			  div>		
			  <div class="form-group">
			    <label for="usercaption" class="col-sm-2 control-label">生日label>
			    <div class="col-sm-6">
			      <input type="text" class="form-control" id="birthday" name="birthday" placeholder="请输入生日">
			    div>
			  div>
			  <div class="form-group">
			    <label for="date" class="col-sm-2 control-label">验证码label>
			    <div class="col-sm-3">
			      <input type="text" class="form-control"  >
			    div>
			    <div class="col-sm-2">
			    <img src="./image/captcha.jhtml"/>
			    div>
			  div>
			  <div class="form-group">
			    <div class="col-sm-offset-2 col-sm-10">
			      <input type="submit"  width="100" value="注册" name="submit" border="0"
				    style="background: url('./images/register.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0);
				    height:35px;width:100px;color:white;">
			    div>
			  div>
			form>
	div>
	<div class="col-md-2">div>
div>
div>

	  
	
	<div style="margin-top:50px;">
			<img src="./image/footer.jpg" width="100%" height="78" alt="我们的优势" title="我们的优势" />
		div>

		<div style="text-align: center;margin-top: 5px;">
			<ul class="list-inline">
				<li><a>关于我们a>li>
				<li><a>联系我们a>li>
				<li><a>招贤纳士a>li>
				<li><a>法律声明a>li>
				<li><a>友情链接a>li>
				<li><a target="_blank">支付方式a>li>
				<li><a target="_blank">配送方式a>li>
				<li><a>服务声明a>li>
				<li><a>广告声明a>li>
			ul>
		div>
		<div style="text-align: center;margin-top: 5px;margin-bottom:20px;">
			Copyright © 中公商城 版权所有
		div>
body>
html>

(7)User 代码(和mysql表对应):


package com.zql.pojo;

import java.io.Serializable;

/**

* author:Daniel

* version:1.0

*/

public class User implements Serializable{
	
	private String uid;
	private String username;
	private String password;
	private String email;
	private String name;
	private String sex;
	private String birthday;
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	public User(String uid, String username, String password, String email, String name, String sex, String birthday) {
		super();
		this.uid = uid;
		this.username = username;
		this.password = password;
		this.email = email;
		this.name = name;
		this.sex = sex;
		this.birthday = birthday;
	}
	public String getUid() {
		return uid;
	}
	public void setUid(String uid) {
		this.uid = uid;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getBirthday() {
		return birthday;
	}
	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}
	@Override
	public String toString() {
		return "User [uid=" + uid + ", username=" + username + ", password=" + password + ", email=" + email + ", name="
				+ name + ", sex=" + sex + ", birthday=" + birthday + "]";
	}
}

(8)RegisterServlet 代码:

package com.zql.servlet;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zql.pojo.User;
import com.zql.sevice.RegisterService;
import com.zql.utils.UUIDUtils;


@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		String email = request.getParameter("email");
		String name = request.getParameter("name");
		String sex = request.getParameter("sex");
		String birthday = request.getParameter("birthday");
		
		User user = new User();
		
		user.setUsername(username);
		user.setPassword(password);
		user.setEmail(email);
		user.setName(name);
		user.setSex(sex);
		user.setBirthday(birthday);
		user.setUid(UUIDUtils.getUUID());
		
		RegisterService service = new RegisterService();
		
		service.register(user);
		
		System.out.println("注册成功");
		} catch (SQLException e) {
			
			System.out.println("注册失败");
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
}

(9)RegisterService 代码:


package com.zql.sevice;

import java.sql.SQLException;

import com.zql.dao.RegisterDao;
import com.zql.pojo.User;

/**

* author:Daniel

* version:1.0

*/

public class RegisterService {

	public void register(User user) throws SQLException {
		
		RegisterDao dao = new RegisterDao();
		
		dao.register(user);
		
	}
}

(10)RegisterDao 代码:


package com.zql.dao;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;

import com.zql.pojo.User;
import com.zql.utils.C3P0Utils;

/**

* author:Daniel

* version:1.0

*/

public class RegisterDao {
	public void register(User user) throws SQLException {
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "insert into user values(?,?,?,?,?,?,?)";
		Object [] params = {user.getUid(),user.getUsername(),user.getPassword(),user.getEmail(),user.getName(),user.getSex(),user.getBirthday()};
		qr.update(sql, params);
	}
}

登录前(http://localhost:8080/register/register.html):
Java进阶-request&response (十一)_第26张图片

登录后(http://localhost:8080/register/register.html):

Java进阶-request&response (十一)_第27张图片

1.3、代码优化

1.3.1、问题:每一个表单参数就要写一个getParameter(),不利于开发

方法声明 功能描述
String getParameter(String name) 该方法用于获取某个指定名称的参数值,如果请求消息中没有包含指定名称的参数,getParameter()方法返回null;如果指定名称的参数存在但没有设置值,则返回一个空串;如果请求消息中包含有多个该指定名称的参数,getParameter()方法返回第一个出现的参数值
String[] getParameterValues(String name) HTTP请求消息中可以有多个相同名称的参数(通常由一个包含有多个同名的字段元素的FORM表单生成),如果要获得HTTP请求消息中的同一个参数名所对应的所有参数值,那么就应该使用getParameterValues()方法,该方法用于返回一个String类型的数组
Map getParameterMap() getParameterMap()方法用于将请求消息中的所有参数名和值装入进一个Map对象中返回

getParameter(String name) 获取指定参数的值(单个) 返回值String (显然不行)
getParameterValues(String name) 获取指定参数的多个值 返回值String[]
getParameterMap() 获取整个参数列表的值 返回值Map
Key:代表页面提交过来的参数名
Value:代表页面提交过来的参数名对应的参数值
使用BeanUtils将map数据封装到user对象中需要注意的两个事项:
1.map中的key必须和javabean中的setXXX方法一致
2.Map中的value的类型必须和javabean中的类型保持一致(类型转换异常)

在这里插入图片描述

1.3.2、问题:将生日改为日期类型

(1)添加jar包(上述下载)
Java进阶-request&response (十一)_第28张图片

//类型转换处理异常
		DateConverter converter = new DateConverter();
		
		converter.setPatterns(new String[] {"yyyy-MM-dd hh:mm:ss"});
		
		ConvertUtils.register(converter, java.util.Date.class);

完整(优化)RegisterServlet.java

package com.zql.servlet;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;

import com.mchange.v2.c3p0.codegen.BeangenDataSourceGenerator;
import com.zql.pojo.User;
import com.zql.sevice.RegisterService;
import com.zql.utils.UUIDUtils;

@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
//		String username = request.getParameter("username");
//		String password = request.getParameter("password");
//		String email = request.getParameter("email");
//		String name = request.getParameter("name");
//		String sex = request.getParameter("sex");
//		String birthday = request.getParameter("birthday");
		
		Map<String, String[]> map = request.getParameterMap();	
		
		User user = new User();
		
		DateConverter converter = new DateConverter();
		
		converter.setPatterns(new String[] {"yyyy-MM-dd hh:mm:ss"});
		
		ConvertUtils.register(converter, java.util.Date.class);
		
		BeanUtils.populate(user, map);
	
//		user.setUsername(username);
//		user.setPassword(password);
//		user.setEmail(email);
//		user.setName(name);
//		user.setSex(sex);
//		user.setBirthday(birthday);
		user.setUid(UUIDUtils.getUUID());
		
		RegisterService service = new RegisterService();
		
		service.register(user);
		
		System.out.println("注册成功");
		} catch (Exception e) {
			
			System.out.println("注册失败");
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
}

MySql中,日期类型有哪些? timestamp time date datetime

Java中:

String:可以操作年月日,时分秒(最好使用这个)
java.util.Date; 可以轻松的操作年月日,时分秒 (日期类型转换器)
java.sql.Date; 只能操作年月日,不能操作时分秒 (一般不用)

1.3.3、问题:中文乱码

请求时:只有post才会出现乱码问题,而get不存在乱码问题(是因为tomcat8已经在底层做了处理)

Post提交乱码处理:

服务器对请求体的默认编码是ISO8859-1

解决:

让服务器对请求体的编码格式修改为UTF-8
使用这个方法进行处理乱码问题:request.setCharacterEncoding("utf-8");

1.4、request对象

在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求消息头和请求消息体三部分,因此,在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法,接下来,将详细阐述下这些方法。

1.4.1、request继承树

ServletRequest 请求的顶层接口。规定了普通请求的操作方法。 无法处理http协议HttpServletRequest 是ServletRequest的子接口。 可以处理http协议

1.4.2、request操作请求体

只有post请求才有请求体:

getParameter(String name) 获取指定参数的值(单个) 返回值String (显然不行)
getParameterValues(String name) 获取指定参数的多个值 返回值String[]
getParameterMap() 获取整个参数列表的值 返回值Map
Key:代表页面提交过来的参数名
Value:代表页面提交过来的参数名对应的参数值
使用BeanUtils将map数据封装到user对象中需要注意的两个事项:
1.map中的key必须和javabean中的setXXX方法一致
2.Map中的value的类型必须和javabean中的类型保持一致(类型转换异常)

1.4.3、request和response的执行流程

Java进阶-request&response (十一)_第29张图片

二、案例二:用户注册信息回显前端

2.1、流程分析

Java进阶-request&response (十一)_第30张图片

2.2、代码实现(重定向)

RegisterServlet.java

this.getServletContext().setAttribute("msg", msg);//(1)把提示信息存储到什么地方(ServletContext)
response.sendRedirect("/register/show");//(1)重定向

ShowServlet.java

Object msg = this.getServletContext().getAttribute("msg");

2.3、代码优化(转发)完整代码

RegisterServlet.java

package com.zql.servlet;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;

import com.mchange.v2.c3p0.codegen.BeangenDataSourceGenerator;
import com.zql.pojo.User;
import com.zql.sevice.RegisterService;
import com.zql.utils.UUIDUtils;


@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		String msg = "";
		
		try {
//			String username = request.getParameter("username");
//			String password = request.getParameter("password");
//			String email = request.getParameter("email");
//			String name = request.getParameter("name");
//			String sex = request.getParameter("sex");
//			String birthday = request.getParameter("birthday");
			
			Map<String, String[]> map = request.getParameterMap();	
			
			User user = new User();
			//类型转换处理异常
			DateConverter converter = new DateConverter();
			
			converter.setPatterns(new String[] {"yyyy-MM-dd hh:mm:ss"});
			
			ConvertUtils.register(converter, java.util.Date.class);
			
			BeanUtils.populate(user, map);
			
//			user.setUsername(username);
//			user.setPassword(password);
//			user.setEmail(email);
//			user.setName(name);
//			user.setSex(sex);
//			user.setBirthday(birthday);
			user.setUid(UUIDUtils.getUUID());
			
			RegisterService service = new RegisterService();
			
			service.register(user);
			
			//System.out.println("注册成功");
			
			msg = "恭喜您注册成功!";
			
			//this.getServletContext().setAttribute("msg", msg);//(1)把提示信息存储到什么地方(ServletContext)
			
			//response.sendRedirect("/register/show");//(1)重定向
			
			request.setAttribute("msg", msg);
			
			request.getRequestDispatcher("/show").forward(request, response);//(2)转发
			
			} catch (Exception e) {
				
				//System.out.println("注册失败");
				
				msg = "兄呆,请您重新注册!";
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}
}

ShowServlet.java

package com.zql.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/show")
public class ShowServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		//Object msg = this.getServletContext().getAttribute("msg");
		
		Object msg = request.getAttribute("msg");
		
		if(msg != null) {
			response.getWriter().write("注册成功");
		}else {
			
			response.getWriter().write("注册失败");
		}
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doGet(request, response);
	}

}

显示看数据库和网页面

2.3.1、问题:不同用户间回显信息冲突问题

Java进阶-request&response (十一)_第31张图片
ServletContext 域对象 :能够共享所有用户 作用域范围太大

解决:
缩小这个域对象范围

Request对象作用:
1.操作请求行,头,体
2.作为域对象 范围:一次请求有效
Java进阶-request&response (十一)_第32张图片
解决问题:
使用请求转发解决
Java进阶-request&response (十一)_第33张图片

2.4、讲解:请求转发和重定向的区别

重定向:

Java进阶-request&response (十一)_第34张图片
请求转发:
Java进阶-request&response (十一)_第35张图片

请求转发与重定向的区别:(重点中的重点)*****
1.请求转发是在服务器内部完成,重定向是在客户端进行发生
2.请求转发的速度是比较快,重定向相对来说比较慢
3.请求转发是一次请求一次响应,重定向是两次请求两次响应(多次)
4.请求转发地址栏不发生改变,重定向地址栏发生改变
5.请求转发是在同一台服务器中完成的(内部完成)
重定向可以在不同服务器下完成(外部完成,可以访问外网)

你可能感兴趣的:(#,计算机(Java进阶)初级进阶,阶段,java,servlet,前端)