巧用 Jersey RESTful WebService框架解决文件上传乱码
一、当我们使用jersey框架封装的restful进行文件上传时,会出现中文乱码,试用了过滤器设置编码都不管用。仔细想了很久解决办法,就用一个servelt来代替这个上传的restful接口实现上传的逻辑。
二、不过后来对restful设计风格和jersey底层的初步研究,发现其实可以使用jersey作为入口来接收文件流,处理还是用apache提供的commons-fileupload-1.3.1.jar来实现,内部request请求设置
编码,就不会出现文件乱码
三、前端依旧是angular封装百度提供的webupload指令实现文件的上传和分片存储
四、逻辑如下
前端
后端
ending 附件带示例
二、不过后来对restful设计风格和jersey底层的初步研究,发现其实可以使用jersey作为入口来接收文件流,处理还是用apache提供的commons-fileupload-1.3.1.jar来实现,内部request请求设置
编码,就不会出现文件乱码
三、前端依旧是angular封装百度提供的webupload指令实现文件的上传和分片存储
四、逻辑如下
前端
<!DOCTYPE html> <html> <head> <title>柳絮飞祭奠</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="../plugins/webuploader/webuploader.css" type="text/css"></link> </head> <body class="lx_droparea"> <lx-upload droparea="lx_droparea" id="upload" type="button" value="上传" style="width:80px;"></lx-ui-upload> </body> <script type="text/javascript" src="../plugins/jquery.js"></script> <script type="text/javascript" src="../plugins/angular.min.js"></script> <script type="text/javascript" src="../plugins/webuploader/webuploader.min.js"></script> <script type="text/javascript"> //设置lx.upload的配置信息 var $$runtime = {file:'/JerseyTest/api/1.0/my/upload', "swf":"",debug : true}; var lxUpload=angular.module("lx.upload",[]); /** * * */ lxUpload.directive('lxUpload',function(){ var option = { restrict : 'E', replace : true, template : '<div>上传文件</div>', scope:true, link : function($scope, $element, $attrs) { //声明作用域内上传数据对象 $scope.upload={"id":"","droparea":"","md5":"","length":0,"data":[],"tip":true,"isupload":false}; //设置上传文件id $scope.upload.id="#"+$attrs.id; $scope.upload.droparea="."+$attrs.droparea; WebUploader.Uploader.register({ "before-send-file" : "beforeSendFile" }, { // 时间点1:所有分块进行上传之前调用此函数 beforeSendFile : function(file) { var deferred = WebUploader.Deferred(); // 1、使用md5计算文件的唯一标记,用于断点续传 uploader.md5File(file).then(function(val) { $scope.upload.md5= val; console.log($scope.upload.md5); // 2.1.5延迟解决 deferred.resolve(); }); return deferred.promise(); }, }); var uploader = WebUploader.create({ // swf文件路径 swf : $$runtime.swf, // 文件接收服务端。 server : $$runtime.file, // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick : { id : $scope.upload.id, // 这个id是你要点击上传文件的id,自己设置就好</span> multiple : true }, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! resize : true, dnd:$scope.upload.droparea, auto : true, // 上传并发数 threads : 5, // 开启分片上传 chunked : true, chunkSize : 1 * 1024 * 1024, duplicate :true }); // // 声明WebUploader内【uploadBeforeSend】事件 // uploader.on("beforeFileQueued", function(file) { // if(!$scope.upload.isupload){ // $$alert("请选择文件夹",3); // return false; // } // }); // 声明WebUploader内【uploadBeforeSend】事件 uploader.on("fileQueued", function(block, data) { if($scope.upload.tip){ } $scope.upload.length++; // wenbuploader添加携带参数 }); // 声明WebUploader内【uploadBeforeSend】事件 uploader.on("uploadBeforeSend", function(block, data) { // wenbuploader添加携带参数 console.log($scope.upload.md5); data.fileMd5 = $scope.upload.md5; }); // 声明WebUploader内【uploadSuccess】事件 uploader.on("uploadSuccess", function(file, response) { $scope.upload.data.push(response[0]); $scope.upload.length--; if($scope.upload.length==0){ $scope.$emit('upload', $scope.upload.data); $scope.upload.data=[]; } }); } }; return option; }); //启动应用程序 angular.bootstrap(document,['lx.upload']); </script> </html>
后端
@POST @Path("/upload") @Produces({ MediaType.APPLICATION_JSON + ";charset=UTF-8" }) public String upload(@Context HttpServletRequest request) throws UnsupportedEncodingException { request.setCharacterEncoding("UTF-8"); // 获取或设置md5值 String nFileMd5 = null; // 获取或设置分片数值 String nChunk = "0"; // 文件地址拿去到配置中 File dir = new File(WebConfig.MAIN_UPLOAD_PATH); if (!dir.exists()) { if (!dir.mkdirs()) { throw new RuntimeException("Directory " + WebConfig.MAIN_UPLOAD_PATH + " not exists and can not create directory."); } } File nDirCACHE_PATH = new File(WebConfig.MAIN_UPLOAD_CACHE_PATH); if (!nDirCACHE_PATH.exists()) { if (!nDirCACHE_PATH.mkdirs()) { throw new RuntimeException("Directory " + WebConfig.MAIN_UPLOAD_CACHE_PATH + " not exists and can not create directory."); } } // 验证上传内容了类型 String contentType = request.getContentType(); if ((contentType.indexOf("multipart/form-data") >= 0)) { DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置内存中存储文件的最大值 factory.setSizeThreshold(WebConfig.MAIN_UPLOAD_MAXSIZE); factory.setSizeThreshold(WebConfig.MAIN_UPLOAD_MEMORY_THRESHOLD); // 设置缓存路径 factory.setRepository(new File(WebConfig.MAIN_UPLOAD_CACHE_PATH)); // 创建一个新的文件上传处理程序 ServletFileUpload upload = new ServletFileUpload(factory); // 设置最大上传的文件大小 upload.setFileSizeMax(WebConfig.MAIN_UPLOAD_MAXSIZE); upload.setSizeMax(WebConfig.MAIN_UPLOAD_MAX_REQUEST_SIZE); try { // 解析获取的文件 List<FileItem> formItems = upload.parseRequest(request); for (FileItem file : formItems) { if (file.isFormField()) { String fieldName = file.getFieldName(); if (fieldName.equals("fileMd5")) { // 10.2.1.获取md5值 nFileMd5 = file.getString("utf-8"); } if (fieldName.equals("chunk")) { // 10.2.2.获取分片数值 nChunk = file.getString("utf-8"); } } else { Map<String, Object> nFileMap = new HashMap<String, Object>(); String nFileName = file.getName(); File nFile = new File(WebConfig.MAIN_UPLOAD_PATH + File.separator + nFileMd5); if (!nFile.exists()) { nFile.mkdir(); } file.write(new File(WebConfig.MAIN_UPLOAD_PATH + File.separator + nFileMd5 + File.separator + nChunk)); if (file.isInMemory()) { file.delete(); } } } } catch (Exception e) { e.printStackTrace(); } } return ""; }
ending 附件带示例