springmvc除了可以用InternalResourceVewResolver解析URL视图,还可以用BeanNameViewResolver将视图解析为excel或者pdf等文档视图。
要使用BeanNameViewResolver,需先把它注册进来
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
<property name="viewClass" value = "org.springframework.web.servlet.view.JstlView"></property>
</bean>
如果配置文件中注册了多个视图解析器,可以通过order属性来指定解析顺序,order越小越靠前,优先级越高,springmvc的一系列解析其中,InternalResourceViewResolver默认优先级最底,ContentNegotingViewResolver的优先级最高,所以这里我们也不用指定order了,默认就先用BeanNameViewResolver进行解析,如果发现返回值作为bean的id找不到对应的bean视图,就用InternalResourceViewResolver进行解析。
解析excel视图
BeanNameViewResolver解析excel视图是用AbstractExcelView做为view的实现类,如果你想要解析excel视图,先定义一个bean继承于AbstractExcelView,需要依赖poi库
package com.liuxg.util.view;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.document.AbstractExcelView;
import com.liuxg.task.entity.Task;
/**
* excel视图
* @author liuxg
* @date 2016年4月9日 下午4:08:10
*/
@Component("taskListExcelView")
public class TaskListExcelView extends AbstractExcelView {
@SuppressWarnings("unchecked")
@Override
protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request,
HttpServletResponse response) throws Exception {
List<Task> tasks = (List<Task>) model.get("tasks");
response.setHeader("Content-disposition", "inline;filename="+new String("任务列表".getBytes() , "iso8859-1") + ".xls");
HSSFSheet sheet = workbook.createSheet("tasks");
HSSFRow header = sheet.createRow(0);
header.createCell(0).setCellValue("任务名");
header.createCell(1).setCellValue("任务详细");
header.createCell(2).setCellValue("创建时间");
int rowNum = 1 ;
for(Task task : tasks){
HSSFRow row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(task.getTaskName());
row.createCell(1).setCellValue(task.getTaskDetail());
row.createCell(2).setCellValue(task.getCreateTime());
}
}
}
定义好bean之后,我们用@Component(“taskListExcelView”)把他放到spring容器中,taskListExcelView就是bean的id,接下来我们定义controller
@RequestMapping(value = "/mvcTest5")
public String mvcTest5(ModelMap modelMap) {
List<Task> tasks = new ArrayList<Task>();
Task t = new Task();
t.setCreateTime(new Date());
t.setTaskDetail("taskDetail");
t.setTaskName("taskName");
Task t1 = new Task();
t1.setCreateTime(new Date());
t1.setTaskDetail("taskDetail");
t1.setTaskName("taskName");
tasks.add(t1);
tasks.add(t);
modelMap.addAttribute("tasks", tasks);
return "taskListExcelView" ; //bean的id
}
接下里我们来定义pdf和json以及xml bean
pdf bean需要继承AbstractPdfView,需要依赖lowagie库
package com.liuxg.util.view;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.document.AbstractPdfView;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfWriter;
@Component("taskListPdfView")
public class TaskListPDFView extends AbstractPdfView{
@Override
protected void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer,
HttpServletRequest request, HttpServletResponse response) throws Exception {
List<Task> tasks = (List<Task>) model.get("tasks");
response.setHeader("Content-disposition", "inline;filename="+new String("任务列表".getBytes() , "iso8859-1") + ".xls");
//...
}
}
json bean是继承MappingJackson2JsonView,需要加入Jackson库相关依赖
package com.liuxg.util.view;
import java.util.Map;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
@Component("taskListJsonView")
public class TaskListJsonView extends MappingJackson2JsonView {
/**
* 需要把哪个model渲染到前端
*/
protected Object filterModel(Map<String, Object> model) {
return model.get("tasks");
}
}
xml bean需继承MappingJackson2XmlView,需要加入Jackson相关库
package com.liuxg.util.view;
import java.util.Map;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.xml.MappingJackson2XmlView;
@Component("taskListXmlView")
public class TaskListXmlView extends MappingJackson2XmlView{
@Override
protected Object filterModel(Map<String, Object> model) {
return model.get("tasks");
}
}
在controller中就把返回值指向不同的bean id就可以了,总过的过程可以总结成这样,controller装载数据,放到模型数据中,视图解析器根据controller的返回值解析成不同的view,view就利用模型中的数据进行渲染生成视图。