spring mvc中引入xheditor的步驟(二)

用戶發表文章(Post),在xheditor中寫文字和上傳圖片,交叉進行,圖片文件上傳到了服務器,圖片的名稱,url,大小等信息在上傳的同時須要單獨保存在一張表裏。 javascript

所以在上一篇的UploadController中除了作上傳圖片這事以外,還要向Attachment記錄圖片信息。修改代碼以下: css

@Controller
@RequestMapping("/upload")
public class UploadController {
	private static final Log logger = LogFactory.getLog(UploadController.class);
	@Autowired
	private AttachmentService attachmentService;

	@RequestMapping(value = "/image", method = RequestMethod.POST)
	@ResponseBody
	public String image(HttpServletRequest request,
			HttpSession session,
			@RequestParam("filedata") MultipartFile file) throws Exception {

		// 將圖片按日期分開存放,方便管理
		final String prefix = "upload/images/"
				+ DateUtil.getFormatedDate("yyyy/MM_dd");

		// 存放到web根目錄下,若是日期目錄不存在,則建立,
		// 注意 request.getRealPath("/") 已經標記爲不推薦使用了.
		final String realPath = session.getServletContext().getRealPath(prefix);
		logger.info(realPath);
		File dir = new File(realPath);
		if (!dir.exists()) {
			dir.mkdirs();
		}

		// 如下是真正的上傳部分
		String error = "";
		// 取得原文件名
		String originName = file.getOriginalFilename();
		// 取得文件後綴
		String fileExt = originName.substring(originName.lastIndexOf(".") + 1);
		// 按時間戳生成圖片文件名
		String picture = DateUtil.getFormatedDate("yyyyMMddHHmmss") + "."
				+ fileExt;
		Attachment attachment = new Attachment();
		try {

			IOUtils.copy(file.getInputStream(), new FileOutputStream(new File(dir, picture)));

			//向attachment表中插入一條post_id爲空的圖片記錄
			attachment.setDownloadCount(0);
			attachment.setSize((int) file.getSize());
			attachment.setUrl(prefix + "/" + picture);
			attachment = attachmentService.createAttachment(attachment);

		} catch (Exception e) {
			logger.error("error:", e);
			error = e.getMessage();
		}
		String http = "http://" + request.getServerName()
	                + ":"  
	                + request.getServerPort()      
	                + request.getContextPath();   
		String url =  http + "/" + prefix + "/" + picture;
		//注意這裏的格式(見xheditor文檔)
		//{'err':'',msg:{'url':'XXX/upload/images/2012/11_11/20121111015039.jpg','localname':'個人頭像.jpg','id':'63'}}
		String json = String.format("{'err':'%s',msg:{'url':'%s','localname':'%s','id':'%s'}}",
                                             error, url, originName, attachment.getId());
		return json;
	}
}

稍微解釋一下xheditor json字符串中幾個參數的做用:: html

(1)err:當這個值不爲空時,xheditor會在JSP中彈出一個上傳失敗的對話框並顯示err的內容
(2)url: 最終拼湊的可在瀏覽器中訪問的http圖片地址,xheditor直接根據這個值在editor中顯示圖片
(3)localname:這個值不是必須的,通常用來存儲圖片的名字,是url中的最後部分(也能夠不是,好比我url中的圖片名字是用時間戳命名的,而這裏localname是圖片自己的名字)
(4)id:這個值不是必須的,它表明圖片在attachment表中的id,回傳到JSP,當發表文章作進一步的處理 html5

這張表Attachment和Post是多對一關係,Attachment表中有一個post_id,問題是:保存圖片信息的時候, post_id還不存在(用戶尚未提交Post呢), java

怎麼辦呢? web

咱們能夠在每次上傳時插入一條沒有post_id的圖片記錄,等到用戶真正發表文章的時候,批量更新這些attachment的post_id,相關代碼以下: spring

@Override
public void updateAttachmentsWithPostId(List<Attachment> attchments, Long postId) {
	List<Object[]> batchArgs = new ArrayList<Object[]>();
	if (attchments != null) {
		for (Attachment attachment : attchments) {
			Object[] args = new Object[] { postId, attachment.getId() };
			batchArgs.add(args);
		}
	}

	String sql = "update cms_attachment set post_id = ? where id=?";
	jdbcTemplate.batchUpdate(sql, batchArgs);
}

其間解決了一個@ResponseBody亂碼問題(json字符串中的localname爲中文時回傳到JSP中是亂碼)
在這裏找到了解決辦法:http://www.oschina.net/code/snippet_103691_11482,加入了以下配置: sql

<!-- 解決@ResponseBody亂碼問題, 須要在annotation-driven以前而且spring版本須要3.1.2以上 -->
<!--Spring3.1推薦使用RequestMappingHandlerAdapter -->
<bean
	class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
	<property name="messageConverters">
		<list>
			<bean
				class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
			<bean
				class="org.springframework.http.converter.StringHttpMessageConverter">
				<property name="supportedMediaTypes">
					<list>
						<value>text/plain;charset=UTF-8</value>
					</list>
				</property>
			</bean>
			<bean
				class="org.springframework.http.converter.ResourceHttpMessageConverter" />
			<bean
				class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
			<bean
				class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
			<bean
				class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
		</list>
	</property>
</bean>

咱們能夠從spring日誌中看出加這個配置的做用 json

加以前 數組

[DEBUG] Written [{'err':'',msg:

{'url':'http://localhost:9080/spring/upload/images/2012/11_11/20121111011413.jpg','localname':'個人頭

像.jpg','id':'50'}}] as "text/html" using

[org.springframework.http.converter.StringHttpMessageConverter@93d9c7]

加以後:
[DEBUG] Written [{'err':'',msg:{'url':'http://localhost:9080/spring/upload/images/2012/11_11/20121111015039.jpg','localname':'個人頭像.jpg','id':'63'}}] as "text/plain;charset=UTF-8" using [org.springframework.http.converter.StringHttpMessageConverter@1fdec30]

前臺部分,相關的JS以下:

<script type="text/javascript">
	//圖片預覽
	function previewImage(x){
		$('#preview').attr("src", "${ctx}/" + $(x).find("option:selected").val());
	}
	
	$(document).ready(function() {
		//初始化xhEditor編輯器插件  
		$('#content').xheditor({
			tools : 'full',
			skin : 'default',
			upImgUrl : "${ctx}/upload/image",
			upImgExt : "jpg,jpeg,png,gif",
			html5Upload : false,
			onUpload : insertUpload
		});
		
		//圖片上傳回調函數  
		function insertUpload(arrMsg) {
			//xheditor返回的arrMsg是一個Object數組
			var msg = arrMsg[0];
			
			//(1)其中url插入到編輯器,這樣xheditor才能正常顯示圖片
			var url = msg.url;
			$("#content").append(url);

			//如下步驟不是必須的
			//(2)將attachment_id保存到checkbox中,發表文章時根據這些attachment_id去更新圖片的post_id
			var id = msg.id;
			$("#imagesDiv").append("<input type='checkbox' name='attachments' checked='checked' onclick='return false;' value='"+id+"''/><br>");
			
			//(3)圖片的名字放到下拉列表,用戶從下拉列表 中選擇圖片作爲Post的主題圖片
			var localname = msg.localname;
			var urlWithoutHttp = url.substring(url.indexOf("/upload")+1);
			$("#topicImageUrl").append("<option value='"+urlWithoutHttp+"'>" + localname + "</option>");
		}
		
		
		//聚焦第一個輸入框
		$("#name").focus();
		//爲inputForm註冊validate函數
		$("#inputForm").validate();
		
	});
</script>

相關的form表單元素以下:

<div class="control-group">
	<label class="control-label" for="content">內容:</label>
	<div class="controls">
		<sf:textarea path="content" rows="15" cssClass="span10"/>
	</div>
	<div class="controls" id="imagesDiv" style="display:none">
	</div>
</div>
<div class="control-group">
	<label class="control-label" for="topicImageUrl">主題圖片:</label>
	<div class="controls">
		<sf:select path="topicImageUrl" onchange='previewImage(this)'>
			<sf:option value="">Please select</sf:option>
		</sf:select>
	</div>
</div>
<div class="control-group">
	<label class="control-label" for="hit">圖片預覽:</label>
	<div class="controls">
		<img id="preview" src="" border="0" width="200" height="200" />
	</div>
</div>

最終的效果以下:

相關文章
相關標籤/搜索