概述
基于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自定义视图可以获取更多的内容。