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

这个问题发生的环境是上传文件,我是用的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>

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值