概述
基於spring-mvc自定義視圖,以BeanNameViewResolver作為解析器,以滿足特殊需求。
本文以輸出多個pdf文件的壓縮文件,供前台下載的需求為例;但是不提供服務層實現。
實現
創建AbstractView的實現類
package cn.sinobest.jzpt.zfba.fzyw.xzfy.dfcl.view; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.view.AbstractView; import cn.sinobest.jzpt.zfba.fzyw.xzfy.dfcl.domain.DFCL; import cn.sinobest.jzpt.zfba.fzyw.xzfy.dfcl.service.IZipService; @Component("dfclView") public class DFCLView extends AbstractView { @Resource(name = "fzyw.xzfy.service.zip") private IZipService zipService; @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { /* 1. 設置響應內容類型 */ response.setContentType("Application/Octet-stream;charset=utf-8"); /* 2. 將文件名加入響應頭 */ String zipName = "材料壓縮包" + System.currentTimeMillis() + ".zip"; zipName = new String(zipName.getBytes(), "ISO-8859-1"); response.addHeader("Content-Disposition", "attachment; filename=" + zipName); /* 3. 輸出文件內容 */ @SuppressWarnings("unchecked") List<DFCL> dfclList = (List<DFCL>) model.get("dfclList"); zipService.write(response.getOutputStream(), dfclList); /* 4. 關閉流 */ response.getOutputStream().flush(); response.getOutputStream().close(); } }
說明:
注解Component用於聲明spring的bean
在Controller中返回視圖bean的名稱
private static final String VIEW_DEFAULT = "dfclView"; @RequestMapping("/download") public String download(Model model, String writids) { List<DFCL> dfclList = dfclService.getDFCL(writids); model.addAttribute("dfclList", dfclList); return VIEW_DEFAULT; }
更多內容
注:下面的介紹多以項目框架中的配置為基礎,具體實現類的代碼不便貼出,權作參考。
在spring-mvc中,controller返回的名稱需要經過視圖解析器的解析,解析器找到對應的視圖,並調用對應的方法。
在項目中,一般在Controller的方法返回jsp的相對路徑,即能在前台得到對應的內容,是因為webmvc-config.xml中存在下述的配置:
<bean class="cn.sinobest.jzpt.framework.mvc.localization.ExtInternalResourceViewResolver"> <!--bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"--> <property name="prefix" value=""/> <property name="suffix" value=""/> </bean>
而詳表配置文件,通常是在jsp返回后根據form的formdata屬性異步請求的,對應的controller方法返回"xmlView";前台可以得到對應的xml,並渲染視圖,是因為webmvc-config.xml中存在下述的配置:
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
BeanNameViewResolver解析器試圖將返回的名稱當作視圖bean的name,而webmvc-config.xml中又配置了"xmlView"的視圖:
<bean name="xmlView" class="cn.sinobest.jzpt.framework.mvc.legacysystemsmac.xml.LegacySystemsXMLView"> <property name="xmlTransformer"> <bean class="cn.sinobest.jzpt.framework.mvc.legacysystemsmac.xml.LegacySystemsXMLTransformer"/> </property> </bean>具體研究詳表配置文件的返回,就要看LegacySystemsXMLView和LegacySystemsXMLTransformer的源代碼了。
當需要返回json的時候,controller方法一般返回"jsonView",是因為webmvc-config.xml中存在了BeanNameViewResolver的配置,還有"jsonView"的配置:
<bean name="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> <property name="encoding"> <value type="org.codehaus.jackson.JsonEncoding">UTF8</value> </property> <property name="contentType" value="text/html;charset=UTF-8"/> </bean>
spring提供了一套View和ViewResolver的繼承體系
參考spring自定義視圖可以獲取更多的內容。