目录
1. HttpServletResponse
1.1 下载文件
1.1.1 思路
1.获取下载文件的路径
2.获取下载的文件名
3.让浏览器(Content-Disposition)支持下载文件
4.获取下载文件的输入流
5.创建缓冲区
6.获取输出流对象
7.将FileInputStream写入缓冲区,使用OutputStream将缓冲区的数据输出到客户端
测试数据来源见右下角水印
1.1.2 代码
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取下载文件的路径
String realPath = this.getServletContext().getRealPath("WEB-INF/classes/壁纸.jpg");
//String realPath = "E:\\Java\\JavaWeb\\javaweb-02-servlet\\response\\target\\response\\WEB-INF\\classes\\壁纸.jpg";
System.out.println("获取到的下载文件路径:" + realPath);
//2.下载的文件名
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
System.out.println("获取到的下载文件名:" + filename);
//3.让浏览器(Content-Disposition)支持下载文件
//resp.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("gb2312"), "ISO-8859-1"));
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename,"utf-8"));
//4.获取下载文件的输入流
FileInputStream input = new FileInputStream(realPath);
//5.创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
//6.获取输出流对象
ServletOutputStream output = resp.getOutputStream();
//7.将FileInputStream写入缓冲区,使用OutputStream将缓冲区的数据输出到客户端
while((len = input.read(buffer))>0){
output.write(buffer,0,len);
}
input.close();
output.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.1.3 实现效果
在网址后输入down
1.2 验证码
1.2.1 代码
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器5s自动刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D pen = (Graphics2D)image.getGraphics();//笔
//设置图片背景颜色
pen.setColor(Color.white);
pen.fillRect(0,0,80,20);
//给图片写数据
pen.setColor(Color.BLUE);
pen.setFont(new Font(null,Font.BOLD,20));
pen.drawString(makeNum(),0,20);
System.out.println(makeNum());
//告诉浏览器,这个请求用图片方式打开
resp.setContentType("image/jpeg");
//不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
public String makeNum(){
String s = String.valueOf(new Random().nextInt(9999999));
StringBuffer sb = new StringBuffer();
for(int i=0;i<7-s.length();i++){
sb.append("0");
}
return sb.toString()+s;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.2.2 实现效果
1.2.3 重定向与转发的区别和联系
重定向:
resp.sendRedirect(“img”);
转发:
ServletContext context = this.getServletContext();
context.getRequestDispatcher("/gp").forward(req,resp);
相同点:页面都实现了跳转
不同点:
转发相当于服务器端找页面,再转发给客户端,307
重定向相当于告诉客户端,去找另一个网址,302
1、请求次数
重定向是浏览器向服务器发送一个请求并收到响应后再次向一个新地址发出请求,转发是服务器收到请求后为了完成响应跳转到一个新的地址;重定向至少请求两次,转发请求一次;
2、地址栏不同
重定向地址栏会发生变化,转发地址栏不会发生变化;
3、是否共享数据
重定向两次请求不共享数据,转发一次请求共享数据(在request级别使用信息共享,使用重定向必然出错);
4、跳转限制
重定向可以跳转到任意URL,转发只能跳转本站点资源;
5、发生行为不同
重定向是客户端行为,转发是服务器端行为;
上方是转发,下方是重定向
2. HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过HTTP协议访问服务器,HTTP协议中的所有信息会被封装到HttpServletRequest,通过Request的方法,获得客户端的所有信息。
<form action=${pageContext.request.contextPath}/login method="get">
以get方式提交表单数据至${pageContext.request.contextPath}/login
2.1 获取前端传递的参数
使用的方法:
2.1.1 前端页面
<%@ page contentType="text/html; charset=UTF-8" %>
<html>
<body>
<h2>Hello World!</h2>
<%--这里提交的路径需要寻找项目的路径--%>
<%--${pageContext.request.contextPath}代表当前项目--%>
<form action=${pageContext.request.contextPath}/login method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit">
</form>
</body>
</html>
login指web.xml中配置的servlet的映射地址
2.1.2 xml
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.songhc.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
页面数据经由前端转发至后端
2.1.3 后端获取数据
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入RequestTest");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+" "+password);
}
}
2.2 请求转发
前端页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>登录</h1>
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/login.do" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<%--验证码:--%>
爱好:
<input type="checkbox" name="hobbies" value="女孩">女孩
<input type="checkbox" name="hobbies" value="代码">代码
<input type="checkbox" name="hobbies" value="电影">电影
<input type="checkbox" name="hobbies" value="唱歌">唱歌<br>
<input type="submit">
</form>
</div>
</body>
</html>
后端代码
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobbies");
System.out.println("============");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbies));
System.out.println("============");
//通过请求转发
//这里的'/'代表当前的webapp
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}