说明:样式不一定美观,主要说明上传逻辑和代码细节说明
改进后:
【页面效果】
【jsp页面】
说明:
1:上传核心的两个input 一个name=photourl 一个name=projectUpload; <img>用于回显图片
2:name=photourl的input样式说明: “hidden="hidden" type="hidden" 如果不添加的话 会出现如下效果:影响美观
name=projectUpload样式说明: 事件必须是onchange()事件 不要用处onclick事件,
style=" 73px; overflow: hidden;padding-left: 20px;"中width的定义目的为了隐藏”未选择任何文件“如图
overflow没有调试出用处先保留 padding-left用于美观调间距
1 <tr> 2 <td class="in-lab" width="15%">成果主图:</td> 3 <td class="in-ctt" colspan="3"> 4 <input name="photourl" id="photourl" value="${bean.photourl}" hidden="hidden" type="hidden"/> 5 <div class="uploadBox"> 6 <input type="file" id="projectUpload" name="projectUpload" onchange="upload();" 7 style=" 73px; overflow: hidden;padding-left: 20px;"/> 8 (请上传规格为260*188像素大小的图片) 9 </div> 10 <div class="imageTips"> 11 <img style=" 120px; height: 120px" src="${bean.photourl}" /> 12 </div> 13 </td> 14 </tr>
js代码说明:
1:upload()方法调用uploadImg()方法
2:projectUpload参数是往后台传递的参数 需要与input中的name=projectUpload的值一致
3:id为photourl的input用于接受ajax返回的图片上传路径;
4:class为imageTips的div用于显示上传的图片,因为此处只上传一个图片 所以只显示一个图片需要清空之前的url 否则会出现显示多个图片的情形
1 //成果主图 2 function upload(){ 3 uploadImg(); 4 } 5 function uploadImg(){ 6 //loading 7 $("#loading").ajaxStart(function() { 8 $(this).show(); 9 }).ajaxComplete(function() { 10 $(this).hide(); 11 }); 12 var elementIds=["flag"]; //flag为id、name属性名 13 $.ajaxFileUpload({ 14 url: '/file/upload.jspx',//接口url 15 type: 'post', 16 secureuri: false, //一般设置为false 17 fileElementId: 'projectUpload', // 上传文件的id、name属性名 18 dataType: 'text', //返回值类型,一般设置为json、application/json 19 elementIds: elementIds, //传递参数到服务器 20 success: function(data, status){ 21 22 var temp = $.parseJSON(data); 23 var fileUrl = temp.fileUrl; 24 $("#photourl").val(fileUrl); 25 $(".imageTips").empty(); 26 $(".imageTips").append("<img height="100" width="100" src=""+fileUrl+""></img> "); 27 alert("上传成功!"); 28 }, 29 error: function(data, status, e){ 30 alert(e); 31 } 32 }); 33 }
后台函数:
1:该后台函数已经封装了很多函数,所以只是看下逻辑
2:参数名为projectUpload
1 @RequestMapping( value = "/file/upload.jspx", method = RequestMethod.POST ) 2 public void avatarUpload( @RequestParam( value = "projectUpload", required = false ) MultipartFile file, 3 HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model modelMap ) { 4 JsonMapper mapper = new JsonMapper(); 5 UploadResult result = new UploadResult(); 6 try { 7 doAvatarUpload( file, result, request, response ); 8 } 9 catch( Exception e ) { 10 logger.error( "upload avatar image error.", e ); 11 result.setError( e.getMessage() ); 12 } 13 String json = mapper.toJson( result ); 14 logger.debug( json ); 15 Servlets.writeHtml( response, json ); 16 return; 17 }
【真正上传图片函数】
1 private void doAvatarUpload( MultipartFile file, UploadResult result, HttpServletRequest request, HttpServletResponse response ) 2 throws Exception { 3 // 文件是否存在 4 if( !validateFile( file, result ) ) { 5 return; 6 } 7 Site site = Context.getCurrentSite( request ); 8 User user = Context.getCurrentUser( request ); 9 10 String origFilename = file.getOriginalFilename(); 11 String ext = FilenameUtils.getExtension( origFilename ).toLowerCase(); 12 GlobalUpload gu = site.getGlobal().getUpload(); 13 // 后缀名是否合法 14 if( !validateExt( ext, Uploader.IMAGE, gu, result ) ) { 15 return; 16 } 17 BufferedImage buffImg = ImageIO.read( file.getInputStream() ); 18 19 PublishPoint point = user.getGlobal().getUploadsPublishPoint(); 20 FileHandler fileHandler = point.getFileHandler( pathResolver ); 21 String fileName = "project_" + System.currentTimeMillis() + "." + ext; 22 String pathname = "/project/" + user.getProjectId() + "/" + fileName; 23 String urlPrefix = point.getUrlPrefix(); 24 String fileUrl = urlPrefix + pathname; 25 // 一律存储为jpg 26 fileHandler.storeImage( buffImg, ext, pathname ); 27 result.setFileUrl( fileUrl ); 28 result.setFileName( fileName ); 29 }
【json转换类 还没时间研究】
1 package com.jspxcms.common.util; 2 3 import java.io.IOException; 4 import java.text.SimpleDateFormat; 5 import java.util.SimpleTimeZone; 6 7 import org.apache.commons.lang3.StringUtils; 8 import org.slf4j.Logger; 9 import org.slf4j.LoggerFactory; 10 11 import com.fasterxml.jackson.annotation.JsonInclude.Include; 12 import com.fasterxml.jackson.core.JsonProcessingException; 13 import com.fasterxml.jackson.databind.DeserializationFeature; 14 import com.fasterxml.jackson.databind.JavaType; 15 import com.fasterxml.jackson.databind.ObjectMapper; 16 import com.fasterxml.jackson.databind.SerializationFeature; 17 import com.fasterxml.jackson.databind.util.JSONPObject; 18 19 /** 20 * Json转换类 21 * 22 * @author liufang 23 * 24 */ 25 public class JsonMapper { 26 27 private static Logger logger = LoggerFactory.getLogger(JsonMapper.class); 28 29 private ObjectMapper mapper; 30 31 public JsonMapper() { 32 this(null); 33 } 34 35 public JsonMapper(Include include) { 36 mapper = new ObjectMapper(); 37 // 设置输出时包含属性的风格 38 if (include != null) { 39 mapper.setSerializationInclusion(include); 40 } 41 mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); 42 // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性 43 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 44 } 45 46 /** 47 * 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用. 48 */ 49 public static JsonMapper nonEmptyMapper() { 50 return new JsonMapper(Include.NON_EMPTY); 51 } 52 53 /** 54 * 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。 55 */ 56 public static JsonMapper nonDefaultMapper() { 57 return new JsonMapper(Include.NON_DEFAULT); 58 } 59 60 /** 61 * Object可以是POJO,也可以是Collection或数组。 如果对象为Null, 返回"null". 如果集合为空集合, 返回"[]". 62 */ 63 public String toJson(Object object) { 64 65 try { 66 return mapper.writeValueAsString(object); 67 } catch (IOException e) { 68 logger.warn("write to json string error:" + object, e); 69 return null; 70 } 71 } 72 73 /** 74 * 反序列化POJO或简单Collection如List<String>. 75 * 76 * 如果JSON字符串为Null或"null"字符串, 返回Null. 如果JSON字符串为"[]", 返回空集合. 77 * 78 * 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType) 79 * 80 * @see #fromJson(String, JavaType) 81 */ 82 public <T> T fromJson(String jsonString, Class<T> clazz) { 83 if (StringUtils.isEmpty(jsonString)) { 84 return null; 85 } 86 87 try { 88 return mapper.readValue(jsonString, clazz); 89 } catch (IOException e) { 90 logger.warn("parse json string error:" + jsonString, e); 91 return null; 92 } 93 } 94 95 /** 96 * 反序列化复杂Collection如List<Bean>, 先使用函數createCollectionType构造类型,然后调用本函数. 97 * 98 * @see #createCollectionType(Class, Class...) 99 */ 100 @SuppressWarnings("unchecked") 101 public <T> T fromJson(String jsonString, JavaType javaType) { 102 if (StringUtils.isEmpty(jsonString)) { 103 return null; 104 } 105 106 try { 107 return (T) mapper.readValue(jsonString, javaType); 108 } catch (IOException e) { 109 logger.warn("parse json string error:" + jsonString, e); 110 return null; 111 } 112 } 113 114 /** 115 * 構造泛型的Collection Type如: ArrayList<MyBean>, 116 * 则调用constructCollectionType(ArrayList.class,MyBean.class) 117 * HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class) 118 */ 119 public JavaType createCollectionType(Class<?> collectionClass, 120 Class<?>... elementClasses) { 121 return mapper.getTypeFactory().constructParametricType(collectionClass, 122 elementClasses); 123 } 124 125 /** 126 * 當JSON裡只含有Bean的部分屬性時,更新一個已存在Bean,只覆蓋該部分的屬性. 127 */ 128 @SuppressWarnings("unchecked") 129 public <T> T update(String jsonString, T object) { 130 try { 131 return (T) mapper.readerForUpdating(object).readValue(jsonString); 132 } catch (JsonProcessingException e) { 133 logger.warn("update json string:" + jsonString + " to object:" 134 + object + " error.", e); 135 } catch (IOException e) { 136 logger.warn("update json string:" + jsonString + " to object:" 137 + object + " error.", e); 138 } 139 return null; 140 } 141 142 /** 143 * 輸出JSONP格式數據. 144 */ 145 public String toJsonP(String functionName, Object object) { 146 return toJson(new JSONPObject(functionName, object)); 147 } 148 149 /** 150 * 設定是否使用Enum的toString函數來讀寫Enum, 為False時時使用Enum的name()函數來讀寫Enum, 默認為False. 151 * 注意本函數一定要在Mapper創建後, 所有的讀寫動作之前調用. 152 */ 153 public void enableEnumUseToString() { 154 mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); 155 mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); 156 } 157 158 /** 159 * 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。 160 * 默认会先查找jaxb的annotation,如果找不到再找jackson的。 161 */ 162 // public void enableJaxbAnnotation() { 163 // JaxbAnnotationModule module = new JaxbAnnotationModule(); 164 // mapper.registerModule(module); 165 // } 166 167 /** 168 * 取出Mapper做进一步的设置或使用其他序列化API. 169 */ 170 public ObjectMapper getMapper() { 171 return mapper; 172 } 173 }
【结果类 有时间研究】
1 package com.jspxcms.common.upload; 2 3 import java.util.Date; 4 import java.util.Locale; 5 6 import org.springframework.context.MessageSource; 7 8 public class UploadResult { 9 /** 10 * 错误状态码 11 */ 12 public static final int ERROR_STATUS = 500; 13 14 private int status = 0; 15 private String message; 16 private String fileUrl; 17 private String fileName; 18 private long fileLength; 19 private String fileExtension; 20 private String pdfUrl; 21 private String swfUrl; 22 private int fileId; 23 24 private Date time; 25 private MessageSource messageSource; 26 private Locale locale; 27 28 public UploadResult() { 29 } 30 31 public UploadResult(String fileUrl, String fileName, String fileExtension, 32 long fileLength) { 33 set(fileUrl, fileName, fileExtension, fileLength); 34 } 35 36 public void setMessageSource(MessageSource messageSource, Locale locale) { 37 this.messageSource = messageSource; 38 this.locale = locale; 39 } 40 41 public void set(String fileUrl, String fileName, String fileExtension, 42 long fileLength) { 43 this.fileUrl = fileUrl; 44 this.fileName = fileName; 45 this.fileExtension = fileExtension; 46 this.fileLength = fileLength; 47 } 48 49 public void set(Integer fileId, String fileUrl, String fileName, String fileExtension, 50 long fileLength, String pdfUrl, String swfUrl) { 51 this.fileId = fileId; 52 this.fileUrl = fileUrl; 53 this.fileName = fileName; 54 this.fileExtension = fileExtension; 55 this.fileLength = fileLength; 56 this.pdfUrl = pdfUrl; 57 this.swfUrl = swfUrl; 58 } 59 60 public void setError(String message) { 61 this.status = ERROR_STATUS; 62 this.message = message; 63 } 64 65 public void setErrorCode(String code) { 66 setErrorCode(code, null); 67 } 68 69 public void setErrorCode(String code, String[] args) { 70 this.status = ERROR_STATUS; 71 setCode(code, args); 72 } 73 74 public void setCode(String code) { 75 setCode(code, null); 76 } 77 78 public void setCode(String code, String[] args) { 79 if (messageSource != null && locale != null) { 80 setMessage(messageSource.getMessage(code, args, code, locale)); 81 } else { 82 this.message = code; 83 } 84 } 85 86 public boolean isError() { 87 return status >= ERROR_STATUS; 88 } 89 90 public boolean isSuccess() { 91 return !isError(); 92 } 93 94 public int getStatus() { 95 return status; 96 } 97 98 public void setStatus(int status) { 99 this.status = status; 100 } 101 102 public String getMessage() { 103 return message; 104 } 105 106 public void setMessage(String message) { 107 this.message = message; 108 } 109 110 public String getFileUrl() { 111 return fileUrl; 112 } 113 114 public void setFileUrl(String fileUrl) { 115 this.fileUrl = fileUrl; 116 } 117 118 public String getFileName() { 119 return fileName; 120 } 121 122 public void setFileName(String fileName) { 123 this.fileName = fileName; 124 } 125 126 public long getFileLength() { 127 return fileLength; 128 } 129 130 public void setFileLength(long fileLength) { 131 this.fileLength = fileLength; 132 } 133 134 public String getFileExtension() { 135 return fileExtension; 136 } 137 138 public void setFileExtension(String fileExtension) { 139 this.fileExtension = fileExtension; 140 } 141 142 public String getPdfUrl() { 143 return pdfUrl; 144 } 145 146 public void setPdfUrl(String pdfUrl) { 147 this.pdfUrl = pdfUrl; 148 } 149 150 public String getSwfUrl() { 151 return swfUrl; 152 } 153 154 public void setSwfUrl(String swfUrl) { 155 this.swfUrl = swfUrl; 156 } 157 158 public Date getTime() { 159 return time; 160 } 161 162 public void setTime(Date time) { 163 this.time = time; 164 } 165 166 public int getFileId() { 167 return fileId; 168 } 169 170 public void setFileId(int fileId) { 171 this.fileId = fileId; 172 } 173 174 175 }