前后端分离跨域上传图片代码
近来工作上不上特别忙,加上对后台java了解一点,所以就抽时间,写了一个java版本的前后端分离的跨服务器文件上传功能,包括前后端代码。
一、Tomcat服务器部分
1、Tomcat服务器
单独复制一份Tomcat,用来作为文件服务器
1.1 web.xml文件:
需要在该Tomcat的conf目录下的web.xml文件的大概100行添加如下几行(红框内部分):
1.2 server.xml文件:
需要在该Tomcat的conf目录下的server.xml文件做一些端口的修改
1.3 Tomcat下建立文件夹
在该Tomcat的/webapps/ROOT目录下创建一个upload目录,用来存放上传的文件
1.4 启动Tomcat服务器
以上三步做完后,就可以启动Tomcat服务器了,在Tomcat的bin目录下执行 startup.sh 脚本
二、java部分
2.1 jar包
除了其他的jar包以外,还需要以下几个jar包
commons-io-1.3.2.jar
commons-fileupload-1.2.1.jar
jersey-client-1.18.1.jar
jersey-core-1.18.1.jar
jersey-common
2.2 配置文件
2.2.1 spring-mvc.xml文件添加如下部分:
<!-- 上传文件 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--最大上传尺寸 5M --> <property name="maxUploadSize" value="5242880"/> </bean>
2.2.2 config.properties 文件添加如下部分:
#文件服务器地址
uploadHost=http://172.16.5.102:8090/
#上传的文件保存的目录
imgPath = upload/
2.3 java文件
2.3.1 Upload.java
package com.lin.utils; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.FilenameUtils; import org.springframework.web.multipart.MultipartFile; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; /** * 上传文件工具类 * @author libo */ public class Upload { /** * 上传文件 * @param request * @param response * @param serverPath 服务器地址:(http://172.16.5.102:8090/) * @param path 文件路径(不包含服务器地址:upload/) * @return */ public static String upload(Client client, MultipartFile file, HttpServletRequest request,HttpServletResponse response, String serverPath, String path){ // 文件名称生成策略(UUID uuid = UUID.randomUUID()) Date d = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); String formatDate = format.format(d); String str = ""; for(int i=0 ;i <5; i++){ int n = (int)(Math.random()*90)+10; str += n; } // 获取文件的扩展名 String extension = FilenameUtils.getExtension(file.getOriginalFilename()); // 文件名 String fileName = formatDate + str + "." + extension; //相对路径 String relaPath = path + fileName; String a = serverPath + path.substring(0, path.lastIndexOf("/")); File file2 = new File(a); if(!file2.exists()){ boolean mkdirs = file2.mkdirs(); System.out.println(mkdirs); } // 另一台tomcat的URL(真实路径) String realPath = serverPath + relaPath; // 设置请求路径 WebResource resource = client.resource(realPath); // 发送开始post get put(基于put提交) try { resource.put(String.class, file.getBytes()); return fileName+";"+relaPath+";"+realPath; } catch (IOException e) { e.printStackTrace(); return ""; } } /** * 删除文件 * @param filePath(文件完整地址:http://172.16.5.102:8090/upload/1234.jpg) * @return */ public static String delete(String filePath){ try { Client client = new Client(); WebResource resource = client.resource(filePath); resource.delete(); return "y"; } catch (Exception e) { e.printStackTrace(); return "n"; } } }
2.3.2 controller层
package com.lin.controller; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.VelocityConfigurerBeanDefinitionParser; import com.lin.domain.data.ResData; import com.lin.domain.data.ResListData; import com.lin.domain.error.Error; import com.lin.domain.sysUser.SysUser; import com.lin.domain.sysUser.SysUserWithDep; import com.lin.service.SysUserService; import com.lin.utils.Aes; import com.lin.utils.DateTimeUtils; import com.lin.utils.ResponseUtils; import com.lin.utils.Upload; import com.lin.utils.Utils; import com.sun.jersey.api.client.Client; import net.sf.json.JSONObject; /** * 后台用户-controller * @author libo */ @Controller @RequestMapping("/sysUser") public class SysUserController { @Resource private SysUserService sysUserService; @Value(value="${imgPath}") //后台图片保存地址 private String imgPath; @Value(value="${uploadHost}") private String uploadHost; //项目host路径 /** * 后台用户登陆功能 * @return * @throws IOException */ @ResponseBody @RequestMapping(value="/login.do", method=RequestMethod.POST) public void login(HttpServletRequest req, HttpServletResponse res, @RequestParam(required=true) String loginEmail, @RequestParam(required=true) String loginPwd) throws IOException{ //代码省略 }
/** * 根据id查询用户信息(包括部门信息) * @param req * @param res * @param id * @throws IOException */ @ResponseBody @RequestMapping(value="/getSysUser.do", method=RequestMethod.GET) public void getSysUser(HttpServletRequest req, HttpServletResponse res, @RequestParam(required=true) Integer id) throws IOException{ //代码省略 } /** * 更新后台用户信息 * @param req * @param res * @throws IOException */ @ResponseBody @RequestMapping(value="/updateSysUser.do" ,method=RequestMethod.POST) public void updateSysUser(HttpServletRequest req, HttpServletResponse res) throws IOException{ //代码省略 } /** * 添加用户 * @param req * @param res * @throws IOException */ @ResponseBody @RequestMapping(value="/addSysUser.do", method=RequestMethod.POST) public void addSysUser(HttpServletRequest req, HttpServletResponse res) throws IOException { //代码省略 }
/** * 上传用户头像 * @param request * @param response */ @ResponseBody @RequestMapping(value="uploadSysHeadImg.do", method=RequestMethod.POST) public void uploadSysHeadImg(HttpServletRequest request,HttpServletResponse response){ JSONObject jo = new JSONObject(); try { MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); MultipartHttpServletRequest Murequest = resolver.resolveMultipart(request); Map<String, MultipartFile> files = Murequest.getFileMap();//得到文件map对象
// 实例化一个jersey Client client = new Client(); List<String> fileNameList = new ArrayList<>(); List<String> relaPathList = new ArrayList<>(); List<String> realPathList = new ArrayList<>(); for(MultipartFile pic: files.values()){ String uploadInfo = Upload.upload(client, pic, request, response, uploadHost, imgPath);
if(!"".equals(uploadInfo)){ //上传成功
String[] infoList = uploadInfo.split(";");
fileNameList.add(infoList[0]); //文件名
relaPathList.add(infoList[1]); //相对路径
realPathList.add(infoList[2]); //真实完整路径
}else{ //上传失败
fileNameList.add("");
relaPathList.add("");
realPathList.add("");
} } jo.put("success", 1); jo.put("error", null); jo.put("fileNameList", fileNameList); jo.put("relaPathList", relaPathList); jo.put("realPathList", realPathList); }catch (Exception e) { jo.put("success", 0); jo.put("error", "上传失败"); } ResponseUtils.renderJson(response, jo.toString()); } }
其他的java文件省略,然后运行java项目
三、前端部分
3.1 index1-cropper图片剪切上传
<!DOCTYPE html> <html> <head> <title>index1-cropper图片剪切上传</title> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <link rel="stylesheet" href="lib/cropper/dist/cropper.min.css" /> </head> <body> <!-- accept="image/*,camera":表示允许调用相册和摄像头,capture="camera":表示直接打开摄像头--> <!--<input id="btn1" type="file" accept="image/*,camera" capture="camera" style="opacity: 0;"/>--> <input id="btn1" type="file" accept="image/*,camera" style="opacity: 0;"/> <div> <div>上传之前的图片</div> <img id="face_image" style="width:50px;height:50px;border-radius: 25px;border: 1px solid #fff;"/> <div>上传之后服务器的图片</div> <img id="success_image" style="width:50px;height:50px;border-radius: 25px;border: 1px solid #fff;"/> </div> <div> <button id="upload_btn">上传头像</button> <button id="image_save">保存</button> <span></span> </div> <div class="upload-img" style="width:300px;height: 300px;"> <img src=""/> </div> <script src="jquery.min.js"></script> <script src="lib/cropper/dist/cropper.min.js"></script> <script src="lib/canvas-toBlob/canvas-toBlob.js"></script> <script> $(function() { //触发input file $('#upload_btn').click(function() { console.log('模拟点击。。。'); $('#btn1').trigger('click'); }); //图片上传 var $image = $('.upload-img > img'); $image.cropper({ viewMode: 1, // preview: '.img-preview', //不同尺寸预览区 aspectRatio: 1, //裁剪比例,NaN-自由选择区域 autoCropArea: 0.7, //初始裁剪区域占图片比例 crop: function(data) { //裁剪操作回调 console.log(data); } }); var fileName; //选择上传的文件名 $('#btn1').change(function(){ var file = this.files[0]; fileName = file.name; var reader = new FileReader(); //reader回调,重新初始裁剪区 reader.onload = function(){ // 通过 reader.result 来访问生成的 DataURL var url = reader.result; //选择图片后重新初始裁剪区 $image.cropper('reset', true).cropper('replace', url); }; reader.readAsDataURL(file); }); /* * 上传图片 */ $('#image_save').click(function() { var type = $image.attr('src').split(';')[0].split(':')[1]; var canVas = $image.cropper("getCroppedCanvas", {}); //将裁剪的图片加载到face_image $('#face_image').attr('src', canVas.toDataURL()); canVas.toBlob(function(blob) { var formData = new FormData(); formData.append("file", blob, fileName); http://172.16.5.102:9000/index1-cropper%E5%9B%BE%E7%89%87%E5%89%AA%E5%88%87%E4%B8%8A%E4%BC%A0.html $.ajax({ type: "POST", url: 'http://172.16.5.102:8081/ssm_project/sysUser/uploadSysHeadImg.do', data: formData, contentType: false, //必须 processData: false, //必须 dataType: "json", success: function(res){ //清空上传文件的值 $('#btn1').val(''); $('#success_image').attr('src', res.realPathList[0]); }, error : function() { //清空上传文件的值 $('#btn1').val(''); } }); }, type); }); //取消 $("#image_cancel").click(function() { //清空上传文件的值 $(_pageId + inputFileId).val(''); }); }); </script> </body> </html>