Java项目中的下载 与 上传
使用超级链接下载,一般会在浏览器中直接打开,而不是出现下载框
如果要确保出现下载框下载文件,则需要设置response中的参数:
1是要设置用附件的方式下载
Content-Disposition: attachment; filename =
2要设定内容的MIME类型
Content-Type:application/x-msdownload
下载的页面代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>服务器的文件资源 点击下载</h1> <a href="/down/download/a.flv">a.flv</a><br> <a href="/down/download/a.jpg">a.jpg</a><br> <a href="/down/download/a.mp3">a.mp3</a><br> <a href="/down/download/a.mp4">a.mp4</a><br> <a href="/down/download/a.txt">a.txt</a><br> <a href="/down/download/a.zip">a.zip</a><br> <h1>肯定下载</h1> <a href="/down/down?filename=a.jpg">美女.jpg</a><br> </body> </html>
原始servlet
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import sun.misc.BASE64Encoder; /** * 文件下载的Servlet */ public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.接收参数 String filename = new String(request.getParameter("filename")); System.out.println(filename); // 2.完成文件下载: // 2.1设置Content-Type头 String type = this.getServletContext().getMimeType(filename); response.setHeader("Content-Type", type); // 2.3设置文件的InputStream. String realPath = this.getServletContext().getRealPath("/download/"+filename); // 根据浏览器的类型处理中文文件的乱码问题: String agent = request.getHeader("User-Agent"); System.out.println(agent); if(agent.contains("Firefox")){ filename = base64EncodeFileName(filename); }else{ filename = URLEncoder.encode(filename,"UTF-8"); } // 2.2设置Content-Disposition头 response.setHeader("Content-Disposition", "attachment;filename="+filename); InputStream is = new FileInputStream(realPath); // 获得response的输出流: OutputStream os = response.getOutputStream(); int len = 0; byte[] b = new byte[1024]; while((len = is.read(b))!= -1){ os.write(b, 0, len); } is.close(); } public static String base64EncodeFileName(String fileName) { BASE64Encoder base64Encoder = new BASE64Encoder(); try { return "=?UTF-8?B?" + new String(base64Encoder.encode(fileName .getBytes("UTF-8"))) + "?="; } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException(e); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
检查下web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>down</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <description></description> <display-name>DownloadServlet</display-name> <servlet-name>DownloadServlet</servlet-name> <servlet-class>DownloadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DownloadServlet</servlet-name> <url-pattern>/down</url-pattern> </servlet-mapping> </web-app>
原始上传方式要有上传按钮 提交按钮及表单才行
相比之下ocupload(即 one-click-upload 一键上传)要简单的多,只需一个按钮
一键上传的upload()方法需要ocupload的js支持 jquery.ocupload-1.1.2.js
页面上需要引入
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/ocupload/jquery.ocupload-1.1.2.js"></script>
上传的页面代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath }/js/ocupload/jquery.ocupload-1.1.2.js"></script> </head> <body> //文件上传页面三个要素 :<br> 1、表单提交方式必须post <br> 2、设置表单属性encty="multipart/form-data" <br> 3、在表单中存在input type="file" 必须有name<br> <iframe name="aaaa" style="display: none;"></iframe> <form target="aaaa" action="abc.action" method="post" enctype="multipart/form-data"> <input type="file" name="upload" value="选择文件"> <input type="submit" value="上传"> </form> <hr> 使用ocupload实现文件上传:原理调用upload方法动态修改html元素<br> 1、在页面中提供任意元素 给出Id<br> 2、在页面加载完成后调用upload方法<br> <input type="button" id="myBtn" value="上传"> <script type="text/javascript"> $(function(){ $("#myBtn").upload({ action:'xyz.action', //提交url name:'upload' //提交文件参数名 }); }) </script> </body> </html>
如何解决上传不用刷新问题?
使用<iframe>标签,把表单的target指向iframe,再把iframe隐藏即可
注意:这个一键上传根据其原理是要生成其他的按钮或表单,所以调用upload方法的时候一定要等待页面加载完(即放在$(function(){})中),如果在datagrid中使用,应再放在datagrid生成代码之后,否则会出现需要点击2次或点击无效问题.
项目中上传Action代码:
Action中上传只需要一个File属性就可以了
private File upload;
public void setUpload(File upload) {
this.upload = upload;
}
也可以再知道上传文件的名字和MIME类型
private String uploadFileName;
private String uploadContentType;
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
/** * @Description: 1、将上传文件接收到 2、通过POI将excel文件中数据解析 3、将数据持久化到数据库 */ @Action("areaAction_importXls") public String importXls() throws Exception { List<Area> list = new ArrayList<>(); HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(upload)); //获取标签页 HSSFSheet sheet = workbook.getSheetAt(0); Area area; //获取行 for (Row row : sheet) { //每一行就是一个区域对象 //将标题行忽略 if(row.getRowNum()==0){ continue; } String id = row.getCell(0).getStringCellValue(); String province = row.getCell(1).getStringCellValue(); String city = row.getCell(2).getStringCellValue(); String district = row.getCell(3).getStringCellValue(); String postcode = row.getCell(4).getStringCellValue(); //保证区域对象中 包含省市区汉字 area = new Area(id, province, city, district, postcode, null, null); province = province.substring(0, province.length()-1); city = city.substring(0, city.length()-1); district = district.substring(0, district.length()-1); String all = province+city+district; String[] strings = PinYin4jUtils.getHeadByString(all); String shortcode = StringUtils.join(strings); area.setShortcode(shortcode); //城市编码: shijiazhuang String citycode = PinYin4jUtils.hanziToPinyin(city, ""); area.setCitycode(citycode); list.add(area); // areaService.save(area); } areaService.save(list); return NONE; }
上传的文件名要和属性名一致
//给导入按钮绑定方法 upload方法 $("#button-import").upload({ action:'${pageContext.request.contextPath}/areaAction_importXls.action', name:"upload", onComplete:function(){ // alert('上传完成,刷新数据表格') $("#grid").datagrid("reload"); } });