一.文件上传
1. 引入两个jar包
jar包可以在maven库进行下载,地址:https://mvnrepository.com,一般点击下载量最多的jar进行下载就可以了。
- apache:commons-fileupload.jar
- commons-fileupload.jar这个jar包是依赖commons-io.jar的
2. 代码
前端代码:表单请求方式必须为post,属性为 enctype="multipart/form-data"
才能上传文件。
<form action="后端上传接受地址" method="post" enctype="multipart/form-data"><input type="file" name="picture"/>
</form>
后端代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置请求编码request.setCharacterEncoding("utf-8");//设置响应编码response.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=UTF-8");//上传try {//判断form表单是否是mutipart格式boolean isMultipart=ServletFileUpload.isMultipartContent(request);if(isMultipart) {//判断前台的form是否有mutipart属性FileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);//通过parseRequest解析form中的所有请求字段,并保存到items集合中,(即前台传递的sname,sno,spiture就保存到items里面了)List<FileItem> items = upload.parseRequest(request);//遍历items中的数据(sno,sname,spicture)Iterator<FileItem> iter=items.iterator();while(iter.hasNext()) {FileItem item = iter.next();//getFieldName获取普通表单字段String itemName = item.getFieldName();int sno = -1;String sname = null;//判断前台字段是普通form表单字段(sname,sno),还是文件字段if(item.isFormField()) {if(itemName.equals("sno")) {sno = Integer.parseInt(item.getString("UTF-8"));}else if(itemName.equals("sname")) {sname = item.getString("UTF-8");}else {System.out.println("其他普通表单字段……");}}else {//文件字段//getName()是获取文件名, //a.txt a.docx a.pngString fileName = item.getName();//防止文件重名覆盖,添加一个文件前缀String prefix = UUID.randomUUID().toString().replaceAll("-", "").replaceAll(".", "");fileName = prefix + fileName;//获取文件内容并上传//定义文件路径:指定上传的文件位置(服务器路径)//动态获取服务器路径String path = request.getSession().getServletContext().getRealPath("static/upload");File file = new File(path,fileName);item.write(file); //将文件上传到指定位置System.out.println(fileName+"上传成功!");return;}}}}catch(FileUploadException e) {e.printStackTrace();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}
}
注意问题:
String path = request.getSession().getServletContext().getRealPath("static/upload")
;通过这种方式指定文件的上传路径,文件只会上传到war包中,容易误删,但指定本机地址,如D:\bookimg
,img访问不了。所以就还是第一种方式将文件存放到war包中,即服务器上就好了。项目重新运行会重新编译一次,按道理war包中之前上传的资源是会被清除的,但我测试后发现文件还是存在,但这是好事,这就不用担心文件被清空了。重启是我们手动的行为,如果是重要的文件怕被清空,可以先保存下来到项目中相同的文件路径下再启动即可。如path指定的路径为static/upload
,在重启先可以将war包下的static/upload
文件复制一份到源码中,即使重新编译也会携带上这些文件。这就比较稳妥了。
二、文件下载
不需要依赖任何jar
- 直接通过
<img/>
标签就可以请求到服务器中的图片资源了。 - 如果是文件则通过输出流的形式将文件输出给用户
注意: 文件需要设置响应头,如果是任意类型则通过附件形式指定文件类型,两个响应头都要设置。如果content-Type
指定了具体的响应类型,并且直接在浏览器中显示,则不需要设置content-Disposition
//MIME类型,表示二进制文件,任意类型都可以
response.addHeader("content-Type","application/octet-stream");
//attachement表示以附件的方式下载文件
response.addHeader("content-Disposition","attachement;filename="+fileName);
文件类型 | Content-Type |
---|---|
二进制文件(任何类型的文件) | application/octet-stream |
Word | application/msword |
Excel | application/vnd.ms-excel |
PPT | application/vnd.ms-powerpoint |
图片 | image/gif, image/bmp, image/jpeg |
文本文件 | text/plain |
html网页 | text/html |
代码
public class DownLoadServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {//获取需要下载的文件名String fileName = request.getParameter("filename"); //from表单和a标签参数的获取都用getParameter//下载文件:需要设置消息头response.addHeader("content-Type","application/octet-stream");//MIME类型,这里为二进制文件(任意文件类型都可)response.addHeader("content-Disposition","attachement;filename="+fileName); //attachement为附件,以附件方式获取要下载的文件,filename指定具体文件,包含了文件后缀:abc.txt//Servlet通过文件的地址,将文件转为输入流,读到Servlet中InputStream in = getServletContext().getResourceAsStream("upload/"+fileName);//通过输出流将刚才已经转为输入流的文件输出给用户ServletOutputStream out = response.getOutputStream();byte[] bs = new byte[10];int len = -1;while((len=in.read(bs))!= -1){out.write(bs,0,len);}out.close();}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}