一.响应对象
1.原理
request 和response 对象都是由服务器创建,管理,销毁.
由我们来使用.
继承体系结构:
ServletRequest(接口)<--------继承<-------HttpServletRequest(接口)<--------实现 org.apache.catalina.connector.RequestFacade@6049a827
ServletResponse(接口)<---------继承--- HttpServletResponse(接口)<-------------实现------org.apache.catalina.connector.ResponseFacade@3bec9d4
2.设置响应行
设置响应行: HTTP/1.1 200 ok
setStatus(int code);设置响应状态码
重定向 302
特点:1.两次请求,两次响应
2.地址栏发生变化
3.不仅可以访问内部资源,也可访问外部资源
代码:
// 设置状态码 302 重定向
response.setStatus(302);
// 设置响应头 location
response.setHeader("location","http://127.0.0.1:8080/MyServlet/index.jsp");
// 以上两步可以合成一个简便方法
response.sendRedirect("http://www.baidu.com");
package org.westos.demo;
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 java.io.IOException;
@WebServlet(name = "ServletDemo1", value = "/demo")
public class ServletDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求对象和响应对象,有服务器创建,管理 和销毁。
//请求对象,封装的是浏览器的请求信息。
//响应对象,封装的是给浏览器响应的信息。
//重定向 302:用来做页面跳转,location:重定向的资源路径。
//特点:1.两次请求两次响应。
//2.地址栏会发生变化。
//3.可以跳转内部资源也可以跳转外部资源。
response.setStatus(302);
response.setHeader("location","http://www.baidu.com");
//以上两步可以合成一步
//response.sendRedirect("http://www.baidu.com");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
3.设置响应头
设置响应头: 例如:content-type:text/html;charset=utf-8
setHeader(String headName,String headValue); 设置响应头的名称和值
setDateHeader(String name,long date); 设置日期头
setIntHeader(String name,int count); 设置数字头
(1) 响应HTML
package org.westos.demo;
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 java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "ServletDemo2", value = "/demo2")
public class ServletDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Tomcat默认采用的编码是ISO-8859-1,与浏览器客户端解码不一致,所以在获取流之前设置Tomcat服务器字符打印输出流的编码
//给浏览器响应文本信息。HTML JSON
//响应中文数据会乱码?服务端和客户端使用的编码不一致。
//Tomcat:默认采用的编码是ISO-8859-1
//对应中文乱码我们来设置一下。
response.setCharacterEncoding("utf-8");
//告诉浏览器,你用utf-8去解码 按照html格式去解码
response.setHeader("content-type","text/html;charset=utf-8");
//以上两步,可以合并为一个方法
//response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("我爱你feike");
writer.write("<h1 style='color:red'>这把我们就遇到了高手了</h1>");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
(2) 响应 JSON
package org.westos.demo;
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 java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "ServletDemo3", value = "/demo3")
public class ServletDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//响应JSON格式的文本设置一下Content-Type头
//response.setContentType("application/json;charset=utf-8");
response.setContentType("text/json;charset=utf-8");
//{"usrname":"张三","password":"123456"}
PrintWriter writer = response.getWriter();
writer.write("{\"usrname\":\"张三\",\"password\":\"123456\"}");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
4.设置响应体
响应体响应的是数据 得通过流的方式
获取输出流写出数据
**PrintWriter getWriter();发送字符数据的对象
// 为了防止乱码,我们设置一下服务器对字符流的编码 默认服务器用的是ISO-8859-1
// 所以在获取流之前告诉服务器用什么编码
response.setCharacterEncoding("utf-8");
//告诉浏览器我们用的是什么编码 ,好让浏览器用响应的编码去解码
response.setHeader("content-type","text/html;charset=utf-8");
//以上两个方法可以合二为一
response.setContentType("text/html;charset=utf-8");//作用:设置字符打印输出流的编码,并告诉浏览器用相应的编码去解码
**ServletOutputStream getOutputStream(); 发送字节数据的对象
// 获取字节流 用流向浏览器写出一张图片
ServletOutputStream sos = response.getOutputStream();
// 获取图片的真实路径
String realPath = this.getServletContext().getRealPath("WEB-INF/302.png");
// 获取输入流读取图片
FileInputStream fis = new FileInputStream(new File(realPath));
byte[] by = new byte[1024];
int len = 0;
while ((len = fis.read(by)) != -1) {
sos.write(by, 0, len);
}
package org.westos.demo;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet(name = "ServletDemo4", value = "/demo4")
public class ServletDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//响应字节数据
//图片在/WEB-INF/目录下
ServletOutputStream out = response.getOutputStream();
String realPath = this.getServletContext().getRealPath("/WEB-INF/anli.png");
FileInputStream in = new FileInputStream(new File(realPath));
//通过响应对象,获取字节流,写给浏览器
byte[] bytes = new byte[1024 * 8];
int len=0;
while ((len=in.read(bytes))!=-1){
out.write(bytes);
}
in.close();
out.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
二.验证码
1.写在一个Servlet中
package org.westos.demo2;
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;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet(name = "CheckCodeServlet", value = "/code")
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//验证码
int width = 200;
int height = 100;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//美化图片
//获取画笔
Graphics graphics = image.getGraphics();
//设置画笔的颜色
graphics.setColor(Color.PINK);
//填充背景
graphics.fillRect(0, 0, width, height);
//设置颜色
graphics.setColor(Color.BLUE);
//绘制边框
graphics.drawRect(0, 0, width - 1, height - 1);
//生成随机的验证码
String str = "abdefaghJKLABCEDFEIOBBHF这波啊这波是肉弹冲击圣枪洗礼托就硬托0123456789";
graphics.setColor(Color.GREEN);
graphics.setFont(new Font("宋体", Font.PLAIN, 30));
Random random = new Random();
for (int i = 1; i <= 4; i++) {
int index = random.nextInt(str.length());
char ch = str.charAt(index);
graphics.drawString(String.valueOf(ch), width / 5 * i, height / 2);
}
//画干扰线
graphics.setColor(Color.BLACK);
for (int i = 0; i < 10; i++) {
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
graphics.drawLine(x1,y1,x2,y2);
}
//响应图片
ImageIO.write(image, "png", response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
上述方式可以完成验证码功能,带代码复用性太高
2.单独类的方法进行封装
工具类:
package org.westos.demo3;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
public class VerifyCode {
// https://blog.csdn.net/piaoyinluo2316/article/details/83754145
public static String drawRandomText(int width, int height, BufferedImage verifyImg) {
Graphics2D graphics = (Graphics2D) verifyImg.getGraphics();
graphics.setColor(Color.WHITE);//设置画笔颜色-验证码背景色
graphics.fillRect(0, 0, width, height);//填充背景
graphics.setFont(new Font("微软雅黑", Font.BOLD, 40));
//数字和字母的组合
String baseNumLetter = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
StringBuffer sBuffer = new StringBuffer();
int x = 10; //旋转原点的 x 坐标
String ch = "";
Random random = new Random();
for (int i = 0; i < 4; i++) {
graphics.setColor(getRandomColor());
//设置字体旋转角度
int degree = random.nextInt() % 30; //角度小于30度
int dot = random.nextInt(baseNumLetter.length());
ch = baseNumLetter.charAt(dot) + "";
sBuffer.append(ch);
//正向旋转
graphics.rotate(degree * Math.PI / 180, x, 45);
graphics.drawString(ch, x, 45);
//反向旋转
graphics.rotate(-degree * Math.PI / 180, x, 45);
x += 48;
}
//画干扰线
for (int i = 0; i < 6; i++) {
// 设置随机颜色
graphics.setColor(getRandomColor());
// 随机画线
graphics.drawLine(random.nextInt(width), random.nextInt(height),
random.nextInt(width), random.nextInt(height));
}
//添加噪点
for (int i = 0; i < 30; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
graphics.setColor(getRandomColor());
graphics.fillRect(x1, y1, 2, 2);
}
return sBuffer.toString();
}
/**
* 随机取色
*/
private static Color getRandomColor() {
Random ran = new Random();
Color color = new Color(ran.nextInt(256),
ran.nextInt(256), ran.nextInt(256));
return color;
}
}
Servlet:
package org.westos.demo3;
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;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
@WebServlet(name = "ServletCode", value = "/code2")
public class ServletCode extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//验证码
int width = 200;
int height = 100;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//生成对应宽高的初始图片
// String randomText = VerifyCode.drawRandomText(width, height, verifyImg);
//生成对应宽高的初始图片
String randomText = VerifyCode.drawRandomText(width, height, image);
//单独的一个类方法,出于代码复用考虑,进行了封装。
//功能是生成验证码字符并加上噪点,干扰线,返回值为验证码字符
request.getSession().setAttribute("verifyCode", randomText);
response.setContentType("image/png");//必须设置响应内容类型为图片,否则前台不识别
OutputStream os = response.getOutputStream(); //获取文件输出流
ImageIO.write(image, "png", os);//输出图片流
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
三.请求对象Request
1.获取请求行
1.获取请求行: GET /MyServlet/index.jsp?name=zhangsan&age=23 HTTP/1.1
request.getMethod();//获取请求方式
request.getContextPath();//获取项目名称
request.getRequestURI();//获取URI
request.getRequestURL();//获取URL
request.getRemoteAddr();//获取IP地址
request.getQueryString();//获取请求参数
request.getProtocol();//获取协议版本
package org.westos.demo4;
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 java.io.IOException;
import java.net.URLDecoder;
@WebServlet(name = "ServletDemo5", value = "/demo5")
public class ServletDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求方式
String method = request.getMethod();
System.out.println("请求方式:"+method);//请求方式:GET
//获取项目上下文路径
String path = request.getContextPath();
System.out.println("项目上下文路径"+path);// 项目上下文路径/20200819___war_exploded
//获取统一资源标识符 即映射路径
String uri = request.getRequestURI();
System.out.println("统一资源标识符"+uri);// 统一资源标识符/20200819___war_exploded/demo5
//获取统一资源定位符
StringBuffer url = request.getRequestURL();
System.out.println("统一资源定位符:"+url); // 统一资源定位符:http://localhost:8080/20200819___war_exploded/demo5
//获取ip地址
String ip = request.getRemoteAddr();
System.out.println("ip地址为:"+ip);// ip地址为:0:0:0:0:0:0:0:1
//获取请求参数
String string = request.getQueryString();
System.out.println("请求参数为:"+string);// 请求参数为:username=%22%E5%BC%A0%E4%B8%89%22&password=%22123456%22
/*
* GET请求参数在请求行,POST请求参数在请求体
浏览器会对中文URL进行编码
* */
System.out.println("==============================");
//浏览器会对中文URL进行编码
String s = URLDecoder.decode("%22%E5%BC%A0%E4%B8%89%22", "utf-8");
System.out.println(s);//"张三"
//获取协议版本
String protocol = request.getProtocol();
System.out.println(protocol);//HTTP/1.1
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
2.URI和URI的区别
初学java,最近被一个概念搞得头晕脑胀,就是url和uri的概念和区别,网上查了一大通,发现各种回答眼花缭乱,有百科直接粘贴的,有胡说八道的,有故意绕来绕去的,我估计他自己都没搞懂,按照马士兵的说法就是,通通都是一些冠冕堂皇的套话,说了等于没说,本来就是一个很抽象的概念,还用很抽象的的方式来答复,这不是让人虐心吗?经过我潜心研究了一番,把他们的区别分享给大家,我相信很多新手都不会一下子明白这两个概念的,老鸟勿喷!
首先给大家举个例子,有一家公司的总经理,某天,给了我一张名片,上面写了他的头衔,北京XXX公司总经理 张三,还有他的办公室地址,北京市海淀区长安街35号北京XXX公司总经理办公室,那么,我以后给我的朋友吹牛,我认识北京XXX公司的总经理张三,我的朋友都知道北京XXX公司的总经理是一个叫张三的人,那么,这个头衔就和张三对应起来了,只要一说到这个头衔,大家都知道说的是张三,反应到网络世界,这个头衔就叫做URI,只要你给我一个URI,我就知道它代表了什么,比如,http://www.sina.com.cn代表了新浪网,admin@qq.com代表了某一个人的qq邮箱,你的qq号也是一个URI(腾讯服务器内可以识别就是你的QQ账户),URI就是网络资源的头衔,通过URI标记可以把网络世界里面的每一个事物都加以标记并区分开来。
好的,现在出现了一个问题,你现在知道北京XXX公司总经理是张三,“北京XXX公司总经理”就是张三这个人的URI,可是,我让你亲自去和张三见一面,你做得到吗?你肯定做不到,因为你不知道他的地址,虽然你有他的URI头衔,但是除此以外,你对他具体的情况一无所知,于是你要定位到他,你就必须得到他的办公室地址,通过“北京市海淀区长安街35号北京XXX公司总经理办公室”这个地址,你就找到了张三。反应到网络世界,网络世界里面的每一个资源不光有自己的头衔,还要能够被人访问,被人找到,所以,网络地址是必须的,否则,这个网络资源的存在没有任何意义,这个地址就叫做URL。
通过上面的描述,可以发现,URI强调的是给资源标记命名,URL强调的是给资源定位,但是你会发现,URL显然比URI包含信息更多,我通过URL也可以知道张三是总经理,并且我还知道了他的地址,所以大多数情况下大家觉得给一个网络资源分别命名和给出地址太麻烦,干脆就用地址既当地址用,又当标记名用,所以,URL也充当了WWW万维网里面URI的角色,但是他比URI多了一层意义,我不光知道你叫什么,我还知道你在哪里。我们在浏览器输入的都是URL,因为我们输入的目的是为了找到某一个资源,当然你输入的是URI也是没错的,因为URL也是URI。
总结:URI标记了一个网络资源,仅此而已; URL标记了一个WWW互联网资源(用地址标记),并给出了他的访问地址。(URI是Uniform Resource Identifier,表示是一个资源; URL是Uniform Resource Locator,表示是一个地址,光看英文缩写确实难懂)
URL是URI的子集,所有的URL都是URI,但不是每个URI都是URL,还有可能是URN
3.获取请求头
2.获取请求头:
request.getHeader("user-agent");//获取请求头的值
request.getDateHeader(name);//获取日期头
request.getIntHeader(name)//获取数字头
package org.westos.demo4;
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 java.io.IOException;
@WebServlet(name = "ServletDemo7", value = "/demo7")
public class ServletDemo7 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求头
String header = request.getHeader("user-agent");
String referer = request.getHeader("Referer");
System.out.println(header);
/*
* Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
* */
System.out.println(referer);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
4.获取请求体
3.获取请求体: 请求体:专门用于封装Post请求的 请求参数
获取字符数据: getReader(); 返回一个高效的字符流 我们通过一次读取一行的 方法来获取请求参数数据 然后 拆分字符串获取我们想要的数据
获取字节数据:getInputStream(); 后期上传文件时讲解
package org.westos.demo4;
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 java.io.BufferedReader;
import java.io.IOException;
@WebServlet(name = "ServletDemo8", value = "/demo8")
public class ServletDemo8 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedReader reader = request.getReader();
System.out.println(reader.readLine());
//username=%E5%BC%A0%E4%B8%89&password=123456
String line = reader.readLine();
String[] split = line.split("&");
String[] split1 = split[0].split("=");
System.out.println(split1[0] + "=" + split1[1]);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
5.通用的方式来获取请求参数
4. 通用的方式来获取 请求参数
request.getParameter(name); 通过请求参数的名称来获取值
request.getParameterValues("hobby"); 通过请求参数的名称,来获取值的数组 一般用于复选框
request.getParameterMap(); 获取所有参数的map集合
request.getParameterNames(); 获取所有参数的名称 枚举 不常用 了解
index.jsp
<%--
Created by IntelliJ IDEA.
User: user
Date: 2020/8/19
Time: 11:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div align="center">
<form action="/20200819___war_exploded/demo9" method="get">
用户名:
<input type="text" name="username" id="" value="" placeholder="请输入用户名" maxlength="5" />
<br>
密码:
<input type="password" name="password" placeholder="请输入密码" />
<br>
<!-- 性别有多个 他们的name属性值要一样 -->
性别:
<input type="radio" name="sex" value="1" checked="checked" />
男
<input type="radio" name="sex" value="0" />
女
<input type="radio" name="sex" id="y" value="2" />
<label for="y">妖</label>
<br>
爱好:
<input type="checkbox" name="hobby" value="lanqiu" checked="checked" />
篮球
<input type="checkbox" name="hobby" value="zuqiu" checked="checked" />
足球
<input type="checkbox" name="hobby" id="pp" value="pingpang" />
<label for="pp">乒乓球</label>
<br>
学历:
<select name="xueli">
<option value="babySchool">幼儿园</option>
<option value="xiaoxue">小学</option>
<option value="zhongxue">中学</option>
<option value="daxue" selected="selected">大学</option>
</select>
<br>
邮箱:
<input type="email" name="user_email" />
<br>
你有你个女朋友:
<input type="number" name="points" min="1" max="10" value="1" />
<br>
生日:
<input type="date" name="birthday" />
<br>
个人描述:
<textarea rows="10" cols="20" name="desc">
</textarea>
<br>
<input type="submit" value="提交按钮" />
<input type="reset" value="重置" />
</form>
</div>
</body>
</html>
servlet
package org.westos.demo4;
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 java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;
@WebServlet(name = "ServletDemo9", value = "/demo9")
public class ServletDemo9 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String sex = request.getParameter("sex");
//针对复选框我们要他的值 使用 getParameterValues()
String[] hobbies = request.getParameterValues("hobby");
Arrays.toString(hobbies);
// 获取所有参数的名称 枚举 不常用 了解
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String key = parameterNames.nextElement();
String value = request.getParameter(key);
System.out.println(key+"=="+value);
/*
* username=======李四
password=======123456
sex=======1
hobby=======lanqiu
xueli=======daxue
user_email=======22222@qq.com
points=======1
birthday=======2020-08-12
desc=======aaaaa
* */
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
6.处理中文乱码问题
//通用处理方式:处理get post 请求提交中文数据乱码问题
tomcat 8.0 以上 GET请求 中文参数 不乱码 tomcat已经处理了 我们不用处理
post 请求特有的方式 处理中文乱码
request.setCharacterEncoding("utf-8");
package org.westos.demo;
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 java.io.IOException;
@WebServlet(name = "MyServlet3", value = "/myServlet3")
public class MyServlet3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println(username);
String password = request.getParameter("password");
System.out.println(password);
//张三
//123456
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println(username);
String password = request.getParameter("password");
System.out.println(password);
//张三
//123456
}
}
四.请求转发
1.内部转发的特点
转发的特点:
1.一次请求一次响应
2.地址栏不发生变化
3.只能访问内部站点资源
代码:
request.getRequestDispatcher("/myservlet2").forward(request, response);
package org.westos.demo5;
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 java.io.IOException;
@WebServlet(name = "MyServlet1", value = "/myServlet1")
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求转发(内部转发)
System.out.println("请求到达myServlet1");
System.out.println("处理请求");
System.out.println("转发到MyServlet2");
request.getRequestDispatcher("/myServlet2").forward(request,response);
System.out.println("请求回到myServlet1");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
package org.westos.demo5;
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 java.io.IOException;
@WebServlet(name = "MyServlet2", value = "/myServlet2")
public class MyServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("请求到达myServlet2");
System.out.println("处理请求");
System.out.println("转发到MyServlet3");
request.getRequestDispatcher("/myServlet3").forward(request,response);
System.out.println("请求回到myServlet2");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
package org.westos.demo5;
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 java.io.IOException;
@WebServlet(name = "MyServlet3", value = "/myServlet3")
public class MyServlet3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("myServlet3");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
2.内部转发的原理
3.重定向的原理
4.内部转发和重定向的区别
1、重定向是在浏览器的url上进行,所以不能重定向到WEB-INF目录下的文件;请求转发可以访问WEB-INF目录下的资源;
内部转发:
1.一次请求一次响应
2.地址栏不发生变化
3.只能访问内部站点资源
重定向:
1.两次请求,两次响应
2.地址栏发生变化
3.不仅可以访问内部资源,也可访问外部资源
五.域对象
请求域的范围中共享数据
请求域的范围中共享数据
在一次请求的多个资源之间共享数据
request.setAttribute("name","zhangsan");
request.getAttribute("name");
request.removeAttribute("name");
什么时候使用重定向?什么时候使用转发?
1.如果需要在请求的多个资源中共享数据,则使用转发
2.如一次性的数据存入请求域中,不要使用重定向来跳转资源,使用请求转发。
3.如果说你使用了重定向来跳转资源,还想要在多个资源间共享数据,那么这个数据存在请求域中,就共享不到。
servlet1
package org.westos.demo5;
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 java.io.IOException;
@WebServlet(name = "Servlet1", value = "/servlet1")
public class Servlet1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//req 请求域对象,他也是一个域对象,能够在他所代表的范围内,进行数据的共享。
//请求域:代表的范围是一次请求和响应的范围。
System.out.println("servlet1收到请求了,处理请求,转发到servlet2");
/*内部转发到servlet2*/
/* request.setAttribute("username","卢本伟");
request.getRequestDispatcher("/servlet2").forward(request,response);
*/
/*重定向到servlet2*/
this.getServletContext().setAttribute("username", "隔壁老王");
response.sendRedirect(request.getContextPath()+"/servlet2");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
servlet2
package org.westos.demo5;
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 java.io.IOException;
@WebServlet(name = "Servlet2", value = "/servlet2")
public class Servlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("servlet2收到请求了,处理请求");
/* String username = (String) request.getAttribute("username");
System.out.println(username);//卢本伟*/
Object username = this.getServletContext().getAttribute("username");
System.out.println(username);
//销毁域中数据
this.getServletContext().removeAttribute("username");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
六.路径的书写
//关于路径的书写:都是以 / 开头。
//1.请求转发,不需要写项目的上下文路径。
//2.html,jsp 页面中的路径,都需要写上项目的上下文路径,重定向也需要写上项目的上下文路径。
建议以/开头
服务器内部跳转路径 不需要加项目上下文路径 request.getRequestDispatcher("/myservlet2").forward(request, response);
页面上的路径和重定向 需要加上项目的上下文路径
<img src="/MyServlet/mydemo4" id="img1"></img>
一般来说我们写相对路径