重定向
-
首先设置状态码,设置响应头
//访问Demo1自动跳转至Demo2 //设置状态码 response.setStatus(302); //设置响应头 response.setHeader("location","/response/responseDemo2");
-
通过sendRedirect(String location)方法完成重定向
//访问Demo1自动跳转至Demo2 response.sendRedirect("/response/responseDemo2");
重定向特点 :
redirect
-
地址栏发生变化
-
重定向可以访问其他站点(服务器)的资源
response.sendRedirect("https://www.baidu.com");
-
重定向是两次请求
转发的特点:
forward
- 转发路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象来共享数据
路径写法:
路径分类
- 相对路径
- 找到当前资源和目标资源之间的位置关系
- 绝对路径:通过绝对路径可以确定唯一资源
- 规则:判断定义的路径是给谁用的
- 客户端浏览器:需要加虚拟目录(项目的访问路径)
- 给服务器用:不需要加虚拟目录
- 规则:判断定义的路径是给谁用的
-
服务器输出字符数据到浏览器
-
步骤
-
获取字符输出流
-
输出数据
-
注意乱码
//设置流的默认编码:ISO-8859-1 设置为GBK,防止乱码 response.setCharacterEncoding("GBK"); //告诉浏览器,服务器发送的消息体数据的编码 //response.setHeader("content-type","text/html;charset=utf-8"); //简单形式。设置编码 response.setContentType("text/html;charset=utf-8"); //获取字符输出流 PrintWriter writer = response.getWriter(); //输出数据 writer.write("hello");
-
服务器输出字节数据到浏览器
-
步骤
- 获取字节输出流
- 输出数据
response.setContentType("text/html;charset=utf-8"); //获取字节输出流 ServletOutputStream outputStream = response.getOutputStream(); //输出数据 outputStream.write("hellow".getBytes());
验证码
- 本质:图片
- 目的:防止恶意操作
servlet代码:
//创建对象,在内存中生成图片(验证码对象)
int width=100;
int height=50;
BufferedImage bufferedImage=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//美化
//填充背景色
Graphics graphics=bufferedImage.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="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
//生成随机角标
Random random=new Random();
int x=0;
for (int j = 0; j < 4; j++) {
int i = random.nextInt(str.length());
char A=str.charAt(i);
graphics.drawString(A+"",x+=20,25);
}
//画线
for (int i = 0; i < 4; i++) {
int x1 = random.nextInt(100);
int x2 = random.nextInt(100);
int y1 = random.nextInt(50);
int y2 = random.nextInt(50);
graphics.drawLine( x1, y1, x2, y2);
}
//输出演示
ImageIO.write(bufferedImage,"jpg",response.getOutputStream());
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<script>
window.onload=function () {
var a=document.getElementById("check");
a.onclick=function () {
//时间戳
var date=new Date().getTime();
a.src="/response/checkCodeServlet?"+date;
}
var b=document.getElementById("change");
b.onclick=function () {
var elementsByName = document.getElementsByTagName("img")
var date=new Date().getTime();
elementsByName[0].setAttribute(src,"/response/checkCodeServlet?"+date)
}
}
</script>
</head>
<body>
<img id="check" src="/response/checkCodeServlet"/>
<a id="change" href="">看不清换一张</a>
</body>
</html>
文件下载 ServletContext
- 文件下载需求:
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片文件下载
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/rui/downloadServlet?filename=1.jpg">图片</a>
</body>
</html>
servlet
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
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.FileInputStream;
import java.io.IOException;
/**
* @author rui
* @create 2019-08-07 22:07
*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取参数文件名
String filename = request.getParameter("filename");
//找到文件真是路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename);
//设置response的响应头类型context-type
//获取文件类型
String mimeType = servletContext.getMimeType(filename);
response.setHeader("context-type",mimeType);
//设置响应头打开方式content-disposition
response.setHeader("content-disposition","attachment;filename="+filename);
response.setContentType("content-disposition:attachment;filename=xxx");
//用字节流关联
FileInputStream fis = new FileInputStream(realPath);
//将输入流写出到输出流
ServletOutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = fis.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
fis.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
-
提示1.jpg是放在web下的img文件中的文件
-
问题:
- 中文文件名问题(中文变成”___“形式)
-
解决:
-
获取客户端使用的浏览器版本信息
-
根据不同的版本信息,设置filename的编码方式
- 代码如下:
使用
DownLoadUtils
工具类import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class DownLoadUtils { public static String getFileName(String agent, String filename) throws UnsupportedEncodingException { if (agent.contains("MSIE")) { // IE浏览器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏览器 BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏览器 filename = URLEncoder.encode(filename, "utf-8"); } return filename; } }
-
在设置响应头前加如下代码:
//解决中文文件名问题 //获取user-agent请求头 String header = request.getHeader("user-agent"); filename = DownLoadUtils.getFileName(header, filename);
-
servlet完整代码:
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
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.FileInputStream;
import java.io.IOException;
/**
* @author rui
* @create 2019-08-07 22:07
*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取参数文件名
String filename = request.getParameter("filename");
//找到文件真是路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename);
//设置response的响应头类型context-type
//获取文件类型
String mimeType = servletContext.getMimeType(filename);
response.setHeader("context-type", mimeType);
//设置响应头打开方式content-disposition
//解决中文文件名问题
//获取user-agent请求头
String header = request.getHeader("user-agent");
filename = DownLoadUtils.getFileName(header, filename);
response.setHeader("content-disposition", "attachment;filename=" + filename);
response.setContentType("content-disposition:attachment;filename=xxx");
//用字节流关联
FileInputStream fis = new FileInputStream(realPath);
//将输入流写出到输出流
ServletOutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = fis.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
fis.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}