您的位置:首页 > 编程语言 > Java开发

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

2017-06-24 19:14 786 查看
这个问题发生的环境是上传文件,我是用的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;

@Controller
public 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()得到的是访问的虚拟路径s
String 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 block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.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 block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.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>

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java web spring
相关文章推荐