前言:本文仅为我的学习笔记,方便今后回顾, 学习来源是B站UP主:遇见狂神说,本文主要讲的是Servlet中的两个请求和相应类,并未涉及Session和Cookie的内容,而且仅是学习的例子,其中有些例子对于已对JavaWeb有全面了解的观众来说是不太恰当的(我是这么认为的),因此这些例子仅单纯用来学习HttpServletResponse类和HttpServletRequest类的部分用法,更多用法请参考这两者的源码,它们的源码很有对应关系,如一个是setxxx,一个是getxxx,and so on…很容易理解,本文就是闹着玩,作为学习记录而已。
文章目录
一、HttpServletResponse
1.下载文件
实例测试:
1)主要代码
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取下载的文件路径;
String realPath = "C:\\Users\\DELL\\Desktop\\IDEA Java代码仓库\\javaweb-02-servlet\\response\\src\\main\\resources\\123.png";
System.out.println("下载文件的路径:" + realPath);
// 2.获取下载的文件名;
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3.设置让浏览器能够识别我们需要的内容,同时指定下载此文件时文件的下载名;
// 中文名用URLEncoder.encode编码,否则可能乱码
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
// 4.获取下载文件的输入流;
FileInputStream in = new FileInputStream(realPath);
// 5.创建缓冲区;
int len = 0;
byte[] buffer = new byte[1024];
// 6.获取OutputStream对象;
ServletOutputStream out = resp.getOutputStream();
// 7.将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区的数据输出到客户端。
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>filedown</servlet-name>
<servlet-class>com.zlc.servlet.response.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>filedown</servlet-name>
<url-pattern>/fd</url-pattern>
</servlet-mapping>
2)效果图
请求此地址
回车后立即下载
2.验证码功能
实例测试:
1)主要代码
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器5s自动刷新一次
resp.setHeader("refresh", "3");
//在内存中创建一个图片
BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片的画笔
Graphics g = bufferedImage.getGraphics();
//设置图片的背景颜色
g.setColor(Color.white);
g.fillRect(0, 0, 80, 20);
//给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null, Font.BOLD, 20));
g.drawString(makeNum(), 0, 20);
//使浏览器以图片形式打开此请求
resp.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
//把图片写给浏览器
ImageIO.write(bufferedImage, "jpg", resp.getOutputStream());
}
//生成随机数
private String makeNum() {
Random random = new Random();
String strNum = random.nextInt(9999999) + "";
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 7 - strNum.length(); i++) {
stringBuffer.append(0);
}
strNum = stringBuffer.toString() + strNum;
return strNum;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>validnum</servlet-name>
<servlet-class>com.zlc.servlet.response.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>validnum</servlet-name>
<url-pattern>/num</url-pattern>
</servlet-mapping>
2)效果图
3.实现重定向
实例测试一:
1)主要代码
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 重定向相当于
* resp.setHeader("Location", "/r/num");
* resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); 302
*/
resp.sendRedirect("/r/num");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>rd</servlet-name>
<servlet-class>com.zlc.servlet.response.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>rd</servlet-name>
<url-pattern>/rd</url-pattern>
</servlet-mapping>
2)效果图
发起请求
地址栏地址立即跳转至预先设定地址
实例测试二:
1)主要代码
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 处理请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username + ":" + password);
resp.sendRedirect("/r/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>req</servlet-name>
<servlet-class>com.zlc.servlet.response.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>req</servlet-name>
<url-pattern>/req</url-pattern>
</servlet-mapping>
index.jsp
<%@ page contentType="text/html; charset=gb2312"%>
<html>
<body>
<h2>Hello World!</h2>
<%--${pageContext.com.zlc.servlet.request.contextPatjsh}:代表当前项目--%>
<form action="${pageContext.com.zlc.servlet.request.contextPath}/req" method="get">
用户名:<input type="text" name="username"> <br/>
密码:<input type="password" name="password"> <br/>
<input type="submit">
</form>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
2)效果图
发起请求
立即跳转
二、HttpServletRequest
1.获取前端传递的参数+请求转发
实例测试:
1)主要代码
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("=========================");
System.out.println("username = " + username);
System.out.println("password = " + password);
System.out.println(Arrays.toString(hobbys));
System.out.println("=========================");
//通过请求转发
req.getRequestDispatcher("/success.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.zlc.servlet.request.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username"> <br/>
密码:<input type="password" name="password"> <br/>
爱好:
<input type="checkbox" name="hobbys" value="read">看书
<input type="checkbox" name="hobbys" value="code">代码
<input type="checkbox" name="hobbys" value="music">音乐
<input type="checkbox" name="hobbys" value="game">游戏 <br/>
<input type="submit">
</form>
</div>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
(注:此例子中因为form表单中action属性的原因,导致请求转发操作中地址栏地址变了,这只是一个不恰当的例子,掩盖不了在很多场景中请求转发本质不改变地址栏的事实。)
2)效果图
提交后
三、请求转发与重定向
有一篇很好的博文,地址是:https://www.cnblogs.com/duanwandao/p/9855229.html
摘选与本文例子有关的部分内容:
请求转发:request.getRequestDispatcher().forward(request,response):
1、属于转发,也是服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页共用一个request,可以通过此来传递一些数据或者session信息,request.setAttribute()和request.getAttribute()。
2、在前后两次执行后,地址栏不变,仍是当前文件的地址。
3、不能转向到本web应用之外的页面和网站,所以转向的速度要快。
4、URL中所包含的“/”表示应用程序(项目)的路径。
重定向:response.sendRedirect():
1、属于重定向,也是客户端跳转,相当于客户端向服务端发送请求之后,服务器返回一个响应,客户端接收到响应之后又向服务端发送一次请求,一共是2次请求,前后页不共用一个request,不能读取转向前通过request.setAttribute()设置的属性值。
2、在前后两次执行后,地址栏发生改变,是目标文件的地址。
3、可以转向到本web应用之外的页面和网站,所以转向的速度相对要慢。
4、URL种所包含的"/"表示根目录的路径。