Servlet
一、实现Servlet
-
创建普通Java类
-
实现Servlet的规范,继承HttpServlet类
-
重写service方法,用来处理请求
-
设置注解,指定访问的路径
快捷键 ctrl + o重写方法;
//@WebServlet(name = "Servlet01",value = "/ser01")
//@WebServlet(name = "Servlet01",value = {"/ser01","/ser001"})
//@WebServlet(name = "Servlet01",urlPatterns = "/ser01")
//@WebServlet(name = "Servlet01",urlPatterns = {"/ser01","/ser001"})
@WebServlet("/ser01") // 路径中的"/"不要忘记写!
public class Servlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 打印内容在控制台
System.out.println("Hello Servlet!");
// 通过流输出数据到浏览器
resp.getWriter().write("Hello Servlet!");
}
}
1.继承GenericServlet类
@WebServlet("/ser02")
public class Servlet02 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("继承GenericServlet类...");
}
}
2.实现Servlet接口
@WebServlet("/ser03")
public class Servlet03 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("实现Servlet接口...");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
3.Get和Post请求调用的方法
@WebServlet("/ser04")
public class Servlet04 extends HttpServlet {
/*@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service...");
}*/
/**
* Get请求调用的方法
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Get请求...");
// 代码
}
/**
* Post请求调用的方法
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Post请求...");
// 调用Get请求
doGet(req,resp);
}
}
4.Servlet的生命周期
@WebServlet("/ser05")
public class Servlet05 extends HttpServlet {
/**
* 就绪/服务方法(处理请求数据)
* 系统方法,服务器自动调用
* 当有请求到达Servlet时,就会调用该方法
* 方法可以被多次调用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet被调用了...");
}
/**
* 销毁方法
* 系统方法,服务器自动调用
* 当服务器关闭或应用程序停止时,调用该方法
* 方法只会执行一次
*/
@Override
public void destroy() {
System.out.println("Servlet被销毁了...");
}
/**
* 初始化方法
* 系统方法,服务器自动调用
* 当请求到达Servlet容器时,Servlet容器会判断该Servlet对象是否存在,如果不存在,则创建实例并初始化
* 方法只会执行一次
* @throws ServletException
*/
@Override
public void init() throws ServletException {
System.out.println("Servlet被创建了...");
}
}
二、HttpServletRequest对象
1.获取请求
获取请求参数
常用方法
/* 常用方法 */
// 获取请求时的完整路径 (从http开始,到"?"前面结束)
String url = request.getRequestURL() + "";
System.out.println("获取请求时的完整路径:" + url);
// 获取请求时的部分路径 (从项目的站点名开始,到"?"前面结束)
String uri = request.getRequestURI();
System.out.println("获取请求时的部分路径:" + uri);
// 获取请求时的参数字符串 (从"?"后面开始,到最后的字符串)
String queryString = request.getQueryString();
System.out.println("获取请求时的参数字符串:" + queryString);
// 获取请求方式 (GET和POST)
String method = request.getMethod();
System.out.println("获取请求方式:" + method);
// 获取当前协议版本 (HTTP/1.1)
String prototol = request.getProtocol();
System.out.println("获取当前协议版本:" + prototol);
// 获取项目的站点名 (项目对外访问路径)
String webapp = request.getContextPath(); // 上下文路径
System.out.println("获取项目的站点名:" + webapp);
/* 获取请求的参数 */
// 获取指定名称的参数值,返回字符串 (重点!!!)
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
System.out.println("uname:" + uname + ",upwd:" + upwd);
// 获取指定名称的参数的所有参数值,返回字符串数组 (用于复选框传值)
String[] hobbys = request.getParameterValues("hobby");
// 判断数组是否为空
if (hobbys != null && hobbys.length > 0) {
for (String hobby: hobbys) {
System.out.println("爱好:" + hobby);
}
2.请求乱码问题
*乱码原因:
**** 由于在解析过程中默认使用的编码方式为 *ISO-8859-1(此编码不支持中文)**,所以解析时一定会出现乱码。
**** 请求乱码问题
*** Tomcat8**及以上版本 Tomcat7及以下版本
*** GET请求 不会乱码,不需要处理 *new String(request.getParameter(name).getBytes(“ISO-8859-1”),“UTF-8”);
*** POST**请求 会乱码,通过设置服务器解析编码的格式 会乱码,通过设置服务器解析编码的格式
-
request.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8");
**** *乱码情况:
*** POST**请求:无论什么版本的服务器,post请求中文都会乱码。(request.setCharacterEncoding(“UTF-8”);)
**** 注:
*** 1. request.setCharacterEncoding(“UTF-8”) 只针对POST请求乱码有效
*** 2. new String(request.getParameter(“uname”).getBytes(“ISO-8859-1”),“UTF-8”) *针对任何请求方式。
**** *但是如果数据本身不乱吗,还依然使用**new String()*方法转换,则会乱码
// 设置请求的编码格式
request.setCharacterEncoding("UTF-8");
// 获取客户端传递的参数
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
System.out.println("姓名:" + uname);
System.out.println("密码:" + upwd);
// 解决Tomcat7及以下版本的GET请求乱码
String name = new String(request.getParameter("uname").getBytes("ISO-8859-1"),"UTF-8");
System.out.println("name:" + name);
3.请求转发跳转
* 请求转发跳转
* request.getRequestDispatcher(url).forward(request,response);
* 可以让请求从服务端跳转到客户端(或跳转到指定Servlet)
*
* 特点:
* 1. 服务端行为
* 2. 地址栏不发生改变
* 3. 从始至终只有一个请求
* 4. request数据可以共享
// 接收客户端请求的参数
String uname = request.getParameter("uname");
System.out.println("Servlet03 uname :" + uname);
// 请求转发跳转到Servlet04
// request.getRequestDispatcher("s04").forward(request,response);
// 请求转发跳转到jsp页面
// request.getRequestDispatcher("login.jsp").forward(request,response);
// 请求转发跳转到html页面
request.getRequestDispatcher("login.html").forward(request,response);
// 接收客户端请求的参数
String uname = request.getParameter("uname");
System.out.println("Servlet04 uname :" + uname);
<form method="get" action="s02">
姓名:<input type="text" name="uname"> <br>
密码:<input type="password" name="upwd"> <br>
<button>登录</button>
</form>
4.request作用域
* request作用域
* 通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。(请求转发跳转时有效)
* // 设置域对象内容
* request.setAttribute(String name, Object value);
* // 获取域对象内容
* request.getAttribute(String name);
* // 删除域对象内容
* request.removeAttribute(String name);
// 设置域对象内容
request.setAttribute("name","admin");
request.setAttribute("age",18);
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
request.setAttribute("list",list);
// 请求转发跳转到Servlet06
// request.getRequestDispatcher("s06").forward(request,response);
// 请求转发跳转到jsp 并通过域对象传递数据
request.getRequestDispatcher("index.jsp").forward(request,response);
// 获取域对象内容
String name = (String) request.getAttribute("name");
System.out.println("name:" + name);
Integer age = (Integer) request.getAttribute("age");
System.out.println("age:" + age);
List<String> list = (List<String>) request.getAttribute("list");
System.out.println(list.get(0));
<%-- 如果要在jsp中写Java代码,需要写在脚本段中--%>
<%
// 获取域对象
// 获取域对象内容
String name = (String) request.getAttribute("name");
System.out.println("name:" + name);
Integer age = (Integer) request.getAttribute("age");
System.out.println("age:" + age);
List<String> list = (List<String>) request.getAttribute("list");
//System.out.println(list.get(0));
%>
三、HttpServletResponse对象
1.响应数据
* 响应数据
* getWriter() 字符输出流 (输出字符串)
* getOutputStream() 字节输出流 (输出一切数据)
*
* 两种流不可同时使用。如果同时使用会报错:java.lang.IllegalStateException: getWriter() has already been called for this response
*
/* getWriter() 字符输出流 (输出字符串) */
// 获取字符输出流
/* PrintWriter writer = response.getWriter();
// 输出数据
writer.write("Hello");*/
/* getOutputStream() 字节输出流 (输出一切数据) */
// 得到字节输出流
ServletOutputStream out = response.getOutputStream();
// 输出数据
out.write("Hi".getBytes());
2.响应乱码问题
1.字符流响应数据
* 字符流响应数据
* 乱码原因:
* 对于 getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。
* 乱码解决:
* 1. 设置服务端的编码格式
* response.setCharacterEncoding("UTF-8");
* 2. 设置客户端的编码格式
* response.setHeader("content-type","text/html;charset=UTF-8");
* 总结:设置客户端和服务端的编码都支持中文,且保持一致。
* 同时设置客户端和服务端的编码格式
* response.setContentType("text/html;charset=UTF-8");
// 设置服务端的编码格式
/* response.setCharacterEncoding("UTF-8");
// 设置客户端的编码格式和响应的MIME类型
response.setHeader("content-type","text/html;charset=UTF-8");*/
// 同时设置客户端和服务端的编码格式
response.setContentType("text/html;charset=UTF-8");
/* getWriter() 字符输出流 (输出字符串) */
// 获取字符输出流
PrintWriter writer = response.getWriter();
// 输出数据
writer.write("<h2>你好</h2>");
2.字节流响应数据
* 乱码问题:
* 对于 getOutputStream()方式获取到的字节流,响应中文时,由于本身就是传输的字节, 所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。
* 乱码解决:
* 1. 设置服务端的编码格式
* response.setCharacterEncoding("UTF-8");
* 2. 设置客户端的编码格式
* response.setHeader("content-type","text/html;charset=UTF-8");
* 总结:设置客户端和服务端的编码都支持中文,且保持一致。
* 同时设置客户端和服务端的编码格式
* response.setContentType("text/html;charset=UTF-8");
// 同时设置客户端和服务端的编码格式
response.setContentType("text/html;charset=UTF-8");
/* getOutputStream() 字节输出流 (输出一切数据) */
// 得到字节输出流
ServletOutputStream out = response.getOutputStream();
// 输出数据
out.write("<h2>你好</h2>".getBytes("UTF-8"));
3.重定向
* 重定向
* 服务端指导,客户端行为
* 存在两次请求
* 地址栏会发生改变
* request对象不共享
System.out.println("Servlet04...");
// 接收参数
String uname = request.getParameter("uname");
System.out.println("Servlet04 " + uname);
// 重定向跳转到s05
response.sendRedirect("s05");
System.out.println("Servlet05...");
// 接收参数
String uname = request.getParameter("uname");
System.out.println("Servlet05 " + uname);
4.重定向与请求转发的区别
* 重定向与请求转发的区别
* 1. 请求转发的地址栏不会发生改变,重定向的地址栏会发生改变
* 2. 请求转发只有一次请求,重定向有两次请求
* 3. 请求转发时request对象可共享,重定向时request对象不共享
* 4. 请求转发是服务端行为,重定向是客户端行为
* 5. 请求转发时的地址只能是当前站点下(当前项目)的资源,重定向时地址可以是任何地址
System.out.println("Servlet06...");
// 接收参数
String uname = request.getParameter("uname");
System.out.println(uname);
// 设置request域对象
request.setAttribute("upwd","123456");
// 请求转发
// request.getRequestDispatcher("index.jsp").forward(request,response);
// 重定向
// response.sendRedirect("index.jsp");
// 重定向跳转到百度
// response.sendRedirect("http://www.baidu.com");
// 请求转发到百度(404)
// request.getRequestDispatcher("http://www.baidu.com").forward(request,response);
<!-- Java脚本段 -->
<%
// 获取参数
String uname = request.getParameter("uname");
// 获取request作用域
String upwd = (String) request.getAttribute("upwd");
// 输出内容
out.print(uname);
out.print("--------");
out.print(upwd);
%>
四、Cookie对象
1.Cookie的创建和发送
// Cookie的创建
Cookie cookie = new Cookie("name","admin");
// 发送(响应)Cookie对象
response.addCookie(cookie);
2.Cookie的获取
返回的是cookie数组
// 获取cookie数组
Cookie[] cookies = request.getCookies();
// 判断cookie是否为空
if (cookies != null && cookies.length > 0) {
// 遍历cookie数组
for (Cookie cookie: cookies ) {
// 获取cookie的名称和值
String name = cookie.getName();
String value = cookie.getValue();
System.out.println("名称:" +name + ",值:" + value);
3.Cookie的到期时间
* 负整数
* 表示只在浏览器内存中存活,关闭浏览器失效。(默认值-1)
* 正整数
* 表示存活指定秒数。单位秒。
* 零
* 表示删除cookie
/* 到期时间:负整数 (默认值-1.表示只在浏览器内存中存活,关闭浏览器失效)*/
Cookie cookie = new Cookie("uname1","zhangsan");
cookie.setMaxAge(-1); // 关闭浏览器失效
response.addCookie(cookie);
/* 到期时间:正整数 (表示存活指定秒数,会将数据存在磁盘中) */
Cookie cookie2 = new Cookie("uname2","lisi");
cookie2.setMaxAge(30); // 存活30秒
response.addCookie(cookie2);
/* 到期时间:零 (表示删除cookie) */
Cookie cookie3 = new Cookie("uname3","wangwu");
cookie3.setMaxAge(0); // 删除cookie
response.addCookie(cookie3);
4.Cookie的注意点
* 1. Cookie只在当前浏览器中有效(不跨浏览器和电脑)
* 2. Cookie不能存中文
* 如果一定要存中文,则需要通过URLEncoder.encode()方法进行编码,获取时通过URLDecoder.decode()方法进行解码
* 3. 如果出现同名的Cookie对象,则会覆盖
* 4. Cookie的存储数量是有上限的,不同浏览器的上限不同。Cookie存储的大小是有效的,在4kb左右
/* Cookie存中文 */
String name = "姓名";
String value = "张三";
// 将中文通过URLEncoder进行编码
name = URLEncoder.encode(name);
value = URLEncoder.encode(value);
// 创建Cookie对象
Cookie cookie = new Cookie(name,value);
// 响应Cookie
response.addCookie(cookie);
// 获取Cookie时,通过URLDecoder进行解码
Cookie[] cookies = request.getCookies();
// 判断非空
if (cookies != null && cookies.length > 0) {
// 遍历
for (Cookie cook : cookies ) {
// 解码
System.out.println(URLDecoder.decode(cook.getName()));
System.out.println(URLDecoder.decode(cook.getValue()));
}
}
// 将原来已有的Cookie对象重新设置
Cookie cookie2 = new Cookie("name","zhangsan");
response.addCookie(cookie2);
5.Cookie的路径
* 1. 当前服务器下任何项目的任意资源都可获取Cookie对象
* 设置路径为"/",表示在当前服务器下任何项目都可访问到Cookie对象
* 2. 当前项目下的资源可获取Cookie对象 (默认不设置Cookie的path)
* 默认不设置Cookie的path 或者 设置为当前站点名
* 3. 指定项目下的资源可获取Cookie对象
* 4. 指定目录下的资源可获取Cookie对象
*
* 总结:只有访问的路径中包含Cookie对象的path值,才可以获取到该cookie对象
/* 当前服务器下任何项目的任意资源都可获取Cookie对象 */
Cookie cookie01 = new Cookie("cookie01","cookie01");
// 设置路径为"/",表示在当前服务器下任何项目都可访问到Cookie对象
cookie01.setPath("/");
response.addCookie(cookie01);
/* 当前项目下的资源可获取Cookie对象 (默认不设置Cookie的path) */
Cookie cookie02 = new Cookie("cookie02","cookie02");
// 默认不设置Cookie的path 或者 设置为当前站点名
cookie02.setPath("/sc04");
response.addCookie(cookie02);
/* 指定项目下的资源可获取Cookie对象 */
Cookie cookie03 = new Cookie("cookie03","cookie03");
// 设置指定项目的站点名
cookie03.setPath("/sr03");
response.addCookie(cookie03);
/* 指定目录下的资源可获取Cookie对象 */
Cookie cookie04 = new Cookie("cookie04","cookie04");
// 设置指定项目的站点名
cookie04.setPath("/sc04/cook02");
response.addCookie(cookie04);
五、HttpSession对象
1.session对象的获取
* request.getSession()
* 当获取session对象时,会先判断session对象是否存在,如果存在,则获取session对象;如果不存在,则创建session对象
* 常用方法
* 获取session的会话标识符 getId()
* 获取session的创建时间 getCreationTime()
* 获取最后一次访问时间 getLastAccessedTime()
* 判断是否是新的session对象 isNew()
*
// 获取session对象
HttpSession session = request.getSession();
// 获取session的会话标识符
String id = session.getId();
System.out.println(id);
// 获取session的创建时间
System.out.println(session.getCreationTime());
// 获取最后一次访问时间
System.out.println(session.getLastAccessedTime());
// 判断是否是新的session对象
System.out.println(session.isNew());
2.Session域对象
* setAttribute() 设置域对象
* getAttribute() 获取域对象
* removeAttribute() 移除域对象
*
* 请求转发
* 一次请求
* request作用域有效
* session作用域有效
* 重定向
* 两次请求
* request作用域无效
* session作用域有效
/* session域对象 */
// 获取session对象
HttpSession session = request.getSession();
// 设置session域对象
session.setAttribute("uname","admin");
session.setAttribute("upwd","123456");
// 移除session域对象
session.removeAttribute("upwd");
/* request域对象 */
request.setAttribute("name","zhangsan");
// 请求转发跳转到jsp页面
// request.getRequestDispatcher("index.jsp").forward(request,response);
// 重定向跳转到index.jsp页面
response.sendRedirect("index.jsp");
<%
// 获取session域对象
String uname = (String) request.getSession().getAttribute("uname");
String upwd = (String) request.getSession().getAttribute("upwd");
// 获取request对象
String name = (String) request.getAttribute("name");
out.print("uname:" + uname + ",upwd:" + upwd + ",name:" + name );
%>
3.Session对象的销毁
* 1. 默认到期时间
* Tomcat 中 session 默认的存活时间为 30min,即你不操作界面的时间,一旦有操作,session 会重新计时。
* 可以在 Tomcat 中的 conf 目录下的 web.xml 文件中进行修改。
* session 默认的最大不活动时间。单位:分钟。
* <session-config>
* <session-timeout>30</session-timeout>
* </session-config>
* 2. 手动设置到期时间
* 可以在程序中自己设定 session 的生命周期。
* 通过session.setMaxInactiveInterval(int) 来设定 session 的最大不活动时间,单位为秒。
* 可以通过 getMaxInactiveInterval() 方法来查看当前 Session 对象的最大不活动时间。
* 3. 立即销毁
* 可以通过 session.invalidate() 方法让 session 立刻失效
* 4. 关闭浏览器
* session底层依赖cookie,cookie对象默认只在浏览器内存中存活,关闭浏览器即失效
* 5. 关闭服务器
* 当关闭服务器时,session 销毁。
/* session域对象 */
// 获取session对象
HttpSession session = request.getSession();
// 设置session域对象
session.setAttribute("uname","admin");
/*// Session 对象的最大不活动时间
System.out.println("Session 对象的最大不活动时间:" + session.getMaxInactiveInterval());
// 修改最大不活动时间
session.setMaxInactiveInterval(15); // 15秒失效*/
// 立即销毁 可以通过 session.invalidate() 方法让 session 立刻失效
// session.invalidate();
六、ServletContext对象
* 获取ServletContext对象
* 1. 通过request对获取
* 2. 通过session对象获取
* 3. 通过ServletConfig对象获取
* 4. 在Servlet中直接获取
*
* 常用方法
* 1. 获取当前服务器的版本信息
* 2. 获取项目的真实路径
// 通过request对获取
ServletContext servletContext1 = request.getServletContext();
// 通过session对象获取
ServletContext servletContext2 = request.getSession().getServletContext();
// 通过ServletConfig对象获取
ServletContext servletContext3 = getServletConfig().getServletContext();
// 直接获取
ServletContext servletContext4 = getServletContext();
// 常用方法
// 1. 获取当前服务器的版本信息
String serverInfo = request.getServletContext().getServerInfo();
System.out.println("获取当前服务器的版本信息: " + serverInfo);
// 2. 获取项目的真实路径
String realPath = request.getServletContext().getRealPath("/");
System.out.println("获取项目的真实路径:" + realPath);
ServletContext域对象
七、文件上传和下载
1.文件上传
HTML:
1. 准备表单
2. 设置表单的提交类型为POST请求 method="post"
3. 设置表单类型为文件上传表单 enctype="multipart/form-data"
4. 设置文件提交的地址
5. 准备表单元素
1. 普通的表单项 type="text"
2. 文件项 type="file"
6. 设置表单元素的name属性值 (表单提交一定要设置表单元素的name属性值,否则后台无法接收数据!)
<form method="post" enctype="multipart/form-data" action="uploadServlet">
姓名:<input type="text" name="uname" > <br>
文件:<input type="file" name="myfile"> <br>
<!--button默认的类型是提交类型 type="submit" -->
<button>提交</button>
</form>
java:
* 文件上传
* 使用注解 @MultipartConfig将一个 Servlet 标识为支持文件上传。
* Servlet 将 multipart/form-data 的 POST 请求封装成 Part对象,通过 Part 对上传的文件进行操作。
@WebServlet("/uploadServlet")
@MultipartConfig // 如果是文件上传,必须要设置该注解!!!
public class UploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("文件上传...");
// 设置请求的编码格式
request.setCharacterEncoding("UTF-8");
// 获取普通表单项(获取参数)
String uname = request.getParameter("uname"); // 表单中表单元素的name属性值
System.out.println("uname:" + uname);
// 获取Part对象 (Servlet 将 multipart/form-data 的 POST 请求封装成 Part对象)
Part part = request.getPart("myfile"); // 表单中file文件域的name属性值
// 通过Part对象得到上传的文件名
String fileName = part.getSubmittedFileName();
System.out.println("上传文件名:" + fileName);
// 得到文件存放的路径
String filePath = request.getServletContext().getRealPath("/");
System.out.println("文件存放的路径:" + filePath);
// 上传文件到指定目录
part.write(filePath +"/"+ fileName);
}
}
2.文件下载
超链接下载
当使用超链接(a标签)时,如果遇到浏览器能够识别的资源,则会显示内容;如果遇到浏览器不能识别的资源,则会进行下载。
download属性
通过download 属性规定浏览器进行下载。
download 属性可以不写任何信息,会自动使用默认文件名。如果设置了download属性的值,则使用设置的值做为文件名。
<a href="download/test.txt">文本文件</a>
<a href="download/bd_logo1.png">图片文件</a>
<!-- 浏览器不能识别的资源 -->
<a href="download/test.rar">压缩文件</a>
<hr>
<a href="download/test.txt" download>文本文件</a>
<a href="download/bd_logo1.png" download="百度.png">图片文件</a>
<hr>
<form action="downloadServlet">
文件名:<input type="text" name="fileName" placeholder="请输入要下载的文件名">
<button>下载</button>
</form>
* 文件下载
*
* 1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 "application/octet-stream" 或 "application/x-msdownload" 等。
* 2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 "attachment;filename=文件名"
* 3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。
System.out.println("文件下载...");
// 设置请求的编码格式
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// 获取参数 (得到要下载的文件名)
String fileName = request.getParameter("fileName");
// 参数的非空判断 trim():去除字符串的前后空格
if (fileName == null || "".equals(fileName.trim())) {
response.getWriter().write("请输入要下载的文件名!");
response.getWriter().close();
return;
}
// 得到图片存放的路径
String path = request.getServletContext().getRealPath("/download/");
// 通过路径得到file对象
File file = new File(path + fileName);
// 判断文件对象是否存在并且是一个标准文件
if (file.exists() && file.isFile()) {
// 设置响应类型 (浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型)
response.setContentType("application/x-msdownload");
// 设置响应头
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
// 得到file文件输入流
InputStream in = new FileInputStream(file);
// 得到字节输出流
ServletOutputStream out = response.getOutputStream();
// 定义byte数组
byte[] bytes = new byte[1024];
// 定义长度
int len = 0;
// 循环输出
while ((len = in.read(bytes)) != -1){
// 输出
out.write(bytes,0,len);
}
// 关闭资源
out.close();
in.close();
} else {
response.getWriter().write("文件不存在,请重试!");
response.getWriter().close();
}