1.附件下载,解决文件名中文下载问题
package context;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
public class DownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//*******文件名称是中文的下载*******
//获得要下载的文件的名称
String filename = request.getParameter("filename");//a.flv
//解决获得中文参数的乱码----下节课讲
//filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg
System.out.println(filename);
/* //获得请求头中的User-Agent
String agent = request.getHeader("User-Agent");
//根据不同浏览器进行不同的编码
String filenameEncoder = "";
if (agent.contains("MSIE")) {
// IE浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
}
*/
//要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
response.setContentType(this.getServletContext().getMimeType(filename));
//告诉客户端该文件不是直接解析 而是以附件形式打开(下载)
//只对chrome有效
String filenameEncoder = URLEncoder.encode(filename, "utf-8");
System.out.println(filenameEncoder);
response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoder);
//获取文件的绝对路径
String path = this.getServletContext().getRealPath("download/" + filename);
System.out.println(path);
//获得该文件的输入流
try (InputStream in = new FileInputStream(path)) {
//获得输出流---通过response获得的输出流 用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
//文件拷贝的模板代码
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
}
//out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
2. request
HttpServletRequest概述
我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。
service方法中的request的类型是ServletRequest,而doGet/doPost方法的request的类型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更加强大,今天我们学习HttpServletRequest。
1.request的运行流程
2.通过抓包工具抓取Http请求
因为request代表请求,所以我们可以通过该对象分别获得Http请求的请求行,请 求头和请求体
3.通过request获得请求行
获得请求的资源:
String
getContextPath()
---web
应用的名称
String
getQueryString()
---- get
提交
url
地址后的参数字符串
username=zhangsan&password=123
注意:request获得客户机(客户端)的一些信息
request.getRemoteAddr() --- 获得访问的客户端IP地址
4.通过request获得请求头
long
getDateHeader(
String name)
Enumeration
getHeaders(
String name)
int
getIntHeader(
String name)
referer头的作用:执行该此访问的的来源
做防盗链
5.通过request获得请求体
请求体中的内容是通过post提交的请求参数,格式是:
username=zhangsan&password=123&hobby=football&hobby=basketball
key ---------------------- value
username [zhangsan]
password [123]
hobby [football,basketball]
以上面参数为例,通过一下方法获得请求参数:
String
getParameter(
String name)
String[]
getParameterValues(
String name)
Enumeration
getParameterNames()
Map<String,String[]>
getParameterMap()
注意:get请求方式的请求参数 上述的方法一样可以获得
解决post提交方式的乱码:request.setCharacterEncoding("UTF-8");
解决get提交的方式的乱码:
parameter = newString(parameter.getbytes("iso8859-1"),"utf-8");
6.request的其他功能
(1)request是一个域对象
request对象也是一个存储数据的区域对象,所以也具有如下方法:
setAttribute(
String name,
Object o)
getAttribute(
String name)
removeAttribute(
String name)
注意:request域的作用范围:一次请求中
(2)request完成请求转发
获得请求转发器----path
是转发的地址
RequestDispatcher
getRequestDispatcher(
String path)
通过转发器对象转发
requestDispatcher.forward(
ServletRequest request,
ServletResponse response)
注意:ServletContext域与Request域的生命周期比较?
ServletContext:
创建:服务器启动
销毁:服务器关闭
域的作用范围:整个web应用
request:
创建:访问时创建request
销毁:响应结束request销毁
域的作用范围:一次请求中
注意:转发与重定向的区别?
1)重定向两次请求,转发一次请求
2)重定向地址栏的地址变化,转发地址不变
3)重新定向可以访问外部网站 转发只能访问内部资源
4)转发的性能要优于重定向
注意:客户端地址与服务器端地址的写法?
客户端地址:
是客户端去访问服务器的地址,服务器外部的地址,特点:写上web应用名 称
直接输入地址:
重定向
服务器端地址:
服务器内部资源的跳转的地址,特点:不需要写web应用的名称
总结:
request获得行的内容
request.getMethod()
request.getRequestURI()
request.getRequestURL()
request.getContextPath()
request.getRemoteAddr()
request获得头的内容
request.getHeader(name)
request获得体(请求参数)
String request.getParameter(name)
Map<String,String[]>request.getParameterMap();
String[] request.getParameterValues(name);
注意:客户端发送的参数 到服务器端都是字符串
获得中文乱码的解决:
post:request.setCharacterEncoding(“UTF-8”);
get:
parameter= new String(parameter.getBytes(“iso8859-1”),”UTF-8”);
request转发和域
request.getRequestDispatcher(转发的地址).forward(req,resp);
request.setAttribute(name,value)
request.getAttribute(name)