场景
比如:填写用户信息的时候,除了填写常规的form表单标签外,还需要上传头像,点击浏览选择头像后,不刷新页面也能马上在页面的文件区域显示所上传的图片
在互联网项目中,经常使用的是图片单独存放在一个服务器,这就是使用了跨服务器上传图片的技术,接下来就介绍如何跨服务器上传图片,springmvc+jersey
准备
服务器
既然说了是跨服务器上传,那么首先需要两台服务器,这里使用两个不同端口的tomcat来作为不同的服务器
一台作为当前项目运行的服务器,一台作为图片服务器
注意:两台服务器需要监听不一样的端口,修改服务器的web.xml
项目
注意:
1.图片服务器项目不需要设置什么,但需要确保在WebContent下有个upload文件夹,初始时需要手动创建upload文件夹以及在下面随意放个文件,启动tomcat后会创建upload文件夹
2.而SSM项目的搭建这里就不再详细介绍,可以参考《SpringMVC之注解以及参数封装》
需要注意的jar包
//这两个是文件上传必需jar包,springmvc使用的是CommonsMultipartResolver,底层是基于这两个jar包的
commons-io-1.3.1.jar
commons-fileupload-1.3.1.jar
//这两个jar包可以实现跨服务器上传文件
jersey-client-1.18.1.jar
jersey-core-1.18.1.jar
开发
一些基础的搭建就不说了,主要说下和主题相关的内容,所以代码并不完整,给大家一个思路
springmvc.xml
// SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件大小上限,单位为字节(10MB) -->
<property name="maxUploadSize">
<value>10485760</value>
</property>
<!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>
UploadController.java
@RequestMapping("/uploadPic")
public void uploadPic(HttpServletRequest request, String fileName, PrintWriter out) throws IOException {
// 将request转化成多部件请求对象
MultipartHttpServletRequest mhsr = (MultipartHttpServletRequest) request;
// 根据文件名称获得文件对象
MultipartFile file = mhsr.getFile(fileName);
// 获得文件上传流
byte[] fileBytes = file.getBytes();
// 设置文件在服务器的随机名字
String newFileName = "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
newFileName = sdf.format(new Date())+new Random().nextInt(9);
// 获取文件扩展名
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// 创建jesy服务器,进行跨服务器上传
Client client = Client.create();
// 将文件关联到远程服务器
// 这里的Commons.PIC_HOST="http://192.168.3.9:8003/SSM_ImageServer",也就是图片服务器
WebResource resource = client.resource(Commons.PIC_HOST+"/upload/"+newFileName+suffix);
// 上传
resource.put(String.class, fileBytes);
// 图片需要回显:绝对路径
// 数据库需要保存:相对路径
// 返回给ajax回调函数
String realPath = Commons.PIC_HOST+"/upload/"+newFileName+suffix;
String relativePath = "/upload/"+newFileName+suffix;
String result = "{\"realPath\":\""+realPath+"\",\"relativePath\":\""+relativePath+"\"}";
out.print(result);
}
edit.jsp
<!-- js代码,需要引入下面两个js文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.form.js"></script>
<script type="text/javascript">
// 给file绑定onchange事件,选完文件后触发此函数
function submitImgSize1Upload(){
var option={
type:'POST',
url:'${pageContext.request.contextPath }/upload/uploadPic.do',
dataType:'text',
data:{
// 这里传送文件名过去,是为了在Controller根据名字取得相应的文件对象MultipartFile
fileName : 'imgSize1File'
},
success:function(data){
//把json格式的字符串转换成json对象
var jsonObj = $.parseJSON(data);
//返回服务器图片路径,把图片路径设置给img标签
$("#imgSize1ImgSrc").attr("src",jsonObj.realPath);
//数据库保存相对路径
$("#imgSize1").val(jsonObj.relativePath);
}
};
// 提交表单
$("#itemForm").ajaxSubmit(option);
}
</script>
<!-- 这部分代码是和图片相关的 -->
<td>商品图片</td>
<td>
<img id='imgSize1ImgSrc' src='${picPath }${item.pic }' height="100" width="100" />
<input type='file' id='imgSize1File' name='imgSize1File' class="file" onchange='submitImgSize1Upload()' />
<input type='hidden' id='imgSize1' name='pic' value='' reg="^.+$" tip="亲!您忘记上传图片了。" />
</td>
页面
选择浏览后,图片区域就会出现上传到图片服务器的图片
问题
做完上述步骤后可能会出现下面问题,图片服务器拒绝访问,图片上传不成功
com.sun.jersey.api.client.UniformInterfaceException: PUT http://192.168.3.9:8003/SSM_ImageServer/upload/201806111755097995.jpg returned a response status of 403 Forbidden
这是需要配置图片服务器所在的tomcat的web.xml文件