关于使用spring文件上传遇到的服务器中的图片访问不到报404的问题

来源:互联网 发布:人工智能2电影 编辑:程序博客网 时间:2024/05/22 16:38

这个问题发生的环境是上传文件,我是用的spring文件上传,上传步骤如下:

首先,applicationContext.xml中配置好文件上传的bean:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

之后导入所用到的jar包,一般来说,MyEclipse集成了spring框架之后,项目下就会自动添加了相关jar包,但是当你布置好了一系列文件上传步骤之后,一测试发现会报500错误,提示找不到类,或者报不是Multipart类型的request等异常,检查jsp,发现<form>中的enctype确实是“multipart/form-data”,后来实在没办法了,他前面提到过找不到类,那会不会是还有jar没有引进去呢,后来发现错误信息里有IOUtils这个字眼,发现项目中依赖的jar包有commons-io这个包,那为什么还会找不到呢,去tomcat的lib文件夹下看了一下,并没有这个jar包,索性把这个jar包考进去试一下,果不其然,不报错了,在这需要提别记录一下,项目中用到的jar包,最好tomcat的lib下也要添加上。

然后我们写一个上传文件的jsp界面(upload.jsp):

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'upload.jsp' starting page</title>    <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>   ${errors}   <form action="upload.do" method="post" enctype="multipart/form-data">   <input type="file" name="file" />   <input type="submit" value="Submit"/>   </form>   <hr/>   <form action="uploadMore.do" method="post" enctype="multipart/form-data">   <input type="file" name="file" /><br/>   <input type="file" name="file"/>   <input type="submit" value="Submit"/>   </form>  </body></html>

再写一个显示结果的界面(result.jsp):

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'result.jsp' starting page</title>    <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body style="font-size:30px;font-style:italic;">    <c:if test="${fileUrl!=null}">    <a href="${fileUrl}">查看</a>    </c:if>    <hr/>    <ul>    <c:forEach items="${fileUrls}" var="url">    <li><a href="${url}">查看</a></li>    </c:forEach>    </ul>    <a href="file:///D:/Install_Location/apache-tomcat-7.0.77/webapps/Demo1/upload_DSC1543.JPG">文件</a>  </body></html>
然后,编写Controller组件:

package com.hardy.test;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.multipart.MultipartFile;@Controllerpublic class UploadController {@RequestMapping("/toUpload.do")public String toLoad(){return "upload";}@RequestMapping("/upload.do")public String upload(@RequestParam(value="file",required=false) MultipartFile file,HttpServletRequest request,ModelMap model){//getRealPath()得到的是磁盘上的真实路径,getContextPath()得到的是访问的虚拟路径sString path = request.getSession().getServletContext().getRealPath("upload");//得到上传文件的名字String fileName = file.getOriginalFilename();System.out.println(path);File targetFile = new File(path,fileName);//创建目录(file.mkdirs()创建路径中不存在的父目录;file.mkdir()只是创建最后的目录,如果路径中有一个目录不存在则创建失败)if(!targetFile.exists()){targetFile.mkdirs();}//保存try {file.transferTo(targetFile);//System.out.println(request.getContextPath()+"/upload/"+fileName);System.out.println(request.getLocalAddr());System.out.println(request.getContextPath());model.addAttribute("fileUrl", request.getContextPath()+"/upload/"+fileName);} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return "result";}@RequestMapping("/uploadMore.do")public String uploadMore(@RequestParam(value="file",required=false) MultipartFile[] files,HttpServletRequest request,ModelMap model){List<String> urls = new ArrayList<String>();for(MultipartFile file:files){String path = request.getServletContext().getRealPath("upload");String fileName = file.getOriginalFilename();System.out.println(path);File targetFile = new File(path,fileName);if(!targetFile.exists()){targetFile.mkdirs();}//保存try {file.transferTo(targetFile);urls.add(request.getContextPath()+"/upload/"+fileName);} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}model.addAttribute("fileUrls",urls);return "result";}}

ModelMap是伴随着request的,所以我们直接给他添加上传文件在服务器中的路径即可,之后在result中通过key(“fileUrl”)或者集合来显示“查看”字样,点击“查看”,你会发现会出现404错误,这就是主问题,而问题的根本就是路径不对,之前我们在html中以链接的形式访问本地图片使用的是绝对路径,在这里只是相对路径,因为他存放在服务器中,所以查看server.xml文件可以看到Context标签下的appBase是webapps,所以它自动会去这个目录下寻找,所以我们只需要返回request.getContextPath+“/upload/”+fileName就能找到相关项目下的文件,这就是为什么fileUrl换成”http://localhost:8080/项目名/upload/文件名”也不行的原因。那这里报错会是什么原因呢,我想,这里和之前练习的唯一不同就是在这里我是用了spring框架,我在web.xml中是这么写的:

<servlet>  <servlet-name>springMVC</servlet-name>  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  <init-param>  <param-name>contextConfigLocation</param-name>  <param-value>classpath:applicationContext.xml</param-value>  </init-param>  <load-on-startup>1</load-on-startup>  </servlet>    <servlet-mapping>  <servlet-name>springMVC</servlet-name>  <url-pattern>/</url-pattern>  </servlet-mapping>

这意味着所有的请求都会经过这个dispatcher,而他又是去查找地址映射的,所以实打实的文件位置的请求是无法被识别的,把url-pattern换成*.do只让.do后缀的请求经过Dispatcher即可,问题迎刃而解。

注意引用JSP的c:..标签时要先进行声明,否则可能会显示异常。

如何限制上传文件大小呢?

在CommonsMultipartResolver中有一个属性maxUploadSize可以设置大小限制:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="51200"></property><property name="resolveLazily" value="true"></property></bean>

此时上传一个大文件则会报错:


阅读全文
2 0
原创粉丝点击