說明:樣式不必定美觀,主要說明上傳邏輯和代碼細節說明java
改進後:ajax
【頁面效果】spring
【jsp頁面】apache
說明:json
1:上傳核心的兩個input 一個name=photourl 一個name=projectUpload; <img>用於回顯圖片 數組
2:name=photourl的input樣式說明: 「hidden="hidden" type="hidden" 若是不添加的話 會出現以下效果:影響美觀服務器
name=projectUpload樣式說明: 事件必須是onchange()事件 不要用處onclick事件, app
style=" width:73px; overflow: hidden;padding-left: 20px;"中width的定義目的爲了隱藏」未選擇任何文件「如圖jsp
overflow沒有調試出用處先保留 padding-left用於美觀調間距ide
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=" width:73px; overflow: hidden;padding-left: 20px;"/> 8 (請上傳規格爲260*188像素大小的圖片) 9 </div> 10 <div class="imageTips"> 11 <img style="width: 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 }