混合多种视图技术:ContentNegotiatingViewResolver
2015-03-17 09:28
363 查看
1. 混合多种视图技术
1.1. 目的
同一资源,多种表述,允许你用同样的内容数据来呈现不同的view1.2. 三种方式
方式1 使用扩展名http://www.test.com/user.xml 呈现xml文件
http://www.test.com/user.json 呈现json格式
http://www.test.com/user 使用默认view呈现,比如jsp等
---------------------------------------------------------------------
方式2 使用http request header的Accept
GET /user HTTP/1.1
Accept:application/xml
GET /user HTTP/1.1
Accept:application/json
---------------------------------------------------------------------
方式3 使用参数
http://www.test.com/user?format=xml
http://www.test.com/user?format=json
1.3. ContentNegotiatingViewResolver配置文件说明
ContentNegotiatingViewResolver:该解析器是Spring 3.0新增的,它不负责具体的视图解析,而是作为一个中间人的角色根据请求所要求的MIME类型,从上下文中选择一个适合的视图解析器,再将视图解析工作委托其负责<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="0" > </bean> <!-- 混合多种视图技术 --> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1" p:defaultContentType="text/html" p:ignoreAcceptHeader="true" p:favorPathExtension="false" p:favorParameter="true" p:parameterName="content" > <property name="mediaTypes"> <map> <entry key="html" value="text/html"></entry> <entry key="xml" value="application/xml"></entry> <entry key="json" value="application/json"></entry> </map> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" p:renderedAttributes="jsonData"> </bean> <bean class="org.springframework.web.servlet.view.xml.MarshallingView" p:modelKey="xmlData" p:marshaller-ref="xmlMarshaller"></bean> </list> </property> </bean> <bean id="xmlMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"> <property name="streamDriver"> <bean class="com.thoughtworks.xstream.io.xml.StaxDriver"></bean> </property> <property name="autodetectAnnotations" ><value>true</value></property> <property name="annotatedClasses"> <list> <value>com.loushi135.model.User</value> </list> </property> </bean> <bean class="org.springframework.web.servlet.view.<span style="font-family: 宋体;">InternalResourceViewResolver</span>" p:order="100" > <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="userListExcelView" class="com.loushi135.view.UserListExcelView"></bean> <bean id="userListPoiExcelView" class="com.loushi135.view.UserListPoiExcelView"></bean> <bean id="userListPdfView" class="com.loushi135.view.UserListPdfView"></bean>说明:
1.BeanNameViewResolver
视图解析器,根据视图的名称new ModelAndView(name),在配置文件查找对应的bean配置,返回视图'userListExcelView'就进入userListExcelView处理
2.defaultContentType
如果所有的mediaType扩展名都没匹配上,就会使用defaultContentType
3.ignoreAcceptHeader
是否忽略掉accept header,默认就是false
4.favorPathExtension
是否启用扩展名支持,默认就是true
5.favorParameter
是否启用参数支持,默认就是true
6.parameterName
参数支持的参数名,默认为format
7.mediaTypes
扩展名至mediaType的映射关系
8.renderedAttributes="jsonData"
json对象根属性
9.xmlMarshaller
也可以使用Jaxb2Marshaller
<span style="color:#333333;"><bean class="org.springframework.web.servlet.view.xml.MarshallingView"> <constructor-arg> <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <array> <value>com.hoo.entity.User</value> <value>com.hoo.entity.AccountBean</value> <value>com.hoo.entity.MapBean</value> </array> </property> </bean> </constructor-arg> </bean></span>10.streamDriver
设置驱动,StaxDriver,DomDriver
1.3.1. UserController
package com.loushi135.controller; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import com.loushi135.model.User; @Controller @RequestMapping("/user") public class UserController { private List<User> userList = new ArrayList<User>(); public UserController() { super(); for(int i = 0;i<5;i++){ User user = new User(); user.setName("loushi"+i); user.setPassword("password"+i); userList.add(user); } } @RequestMapping("/userIndex") public String toUserIndex(){ return "userIndex"; } /** * 返回json数据 */ @RequestMapping("/getJson") public String getJson(ModelMap mm){ mm.addAttribute("jsonData", userList); return "listJson"; } /** * 返回xml数据 */ @RequestMapping("/getXml") public String getXml(ModelMap mm){ mm.addAttribute("xmlData", userList); return "listXml"; } /** * 返回excel数据 */ @RequestMapping("/getExcel") public String getExcel(ModelMap mm){ mm.addAttribute("userList",userList); return "userListE def0 xcelView"; } /** * 返回excel数据 */ @RequestMapping("/getPoiExcel") public String getPoiExcel(ModelMap mm){ mm.addAttribute("userList",userList); return "userListPoiExcelView"; } /** * 返回pdf数据 */ @RequestMapping("/getPdf") public String getPdf(ModelMap mm){ mm.addAttribute("userList",userList); return "userListPdfView"; } }
1.3.2. jxl返回Excel视图
package com.loushi135.view; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jxl.WorkbookSettings; import jxl.format.Alignment; import jxl.format.VerticalAlignment; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; import jxl.write.biff.RowsExceededException; import org.apache.commons.beanutils.PropertyUtils; import org.springframework.web.servlet.view.document.AbstractJExcelView; import com.loushi135.model.User; public class UserListExcelView extends AbstractJExcelView { private String[] columnNames = new String[] {"姓名","密码"}; private String[] dbColumnNames = new String[] {"name","password"}; private Integer[] columnWidths = new Integer[] { 40, 40 }; @Override protected void buildExcelDocument(Map<String, Object> model, WritableWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { try { response.setCharacterEncoding("UTF-8"); response.setContentType("application/ms-excel"); String fileName = "用户列表excel.xls"; // response.setContentType("APPLICATION/OCTET-STREAM"); response.setHeader("Content-Disposition", "inline; filename="+new String(fileName.getBytes(),"iso8859-1")); String sheetName = "用户信息"; // 全局设置 WorkbookSettings setting = new WorkbookSettings(); java.util.Locale locale = new java.util.Locale("zh", "CN"); setting.setLocale(locale); setting.setEncoding("UTF-8"); // 创建工作薄 // workbook = Workbook.createWorkbook(os); // 建立excel文件 // 创建第一个工作表 jxl.write.WritableSheet ws = workbook.createSheet(sheetName, 1); // sheet名称 List<User> userList = (List<User>)model.get("userList"); // 添加标题 addColumNameToWsheet(ws); writeContext(ws, userList); } catch (Exception e) { e.printStackTrace(); } // finally { // 写入文件 // try { // workbook.write(); // workbook.close(); // os.flush(); // os.close(); // } catch (WriteException e) { // e.printStackTrace(); // } catch (IOException e) { // e.printStackTrace(); // } // } } private <T> void writeContext(WritableSheet wsheet, List<T> list) { jxl.write.Label wlabel = null; jxl.write.WritableCellFormat wcf = getFormat(); int rows = list.size(); int cols = dbColumnNames.length; String columnName = null; Object value = null; try { for (int i = 0; i < rows; i++) { T t = (T) list.get(i); for (int j = 0; j < cols; j++) { columnName = dbColumnNames[j].toLowerCase(); value = PropertyUtils.getProperty(t, columnName); wlabel = new jxl.write.Label(j, (i + 1), value + "", wcf); wlabel = new jxl.write.Label(j, (i + 1), value + ""); wsheet.addCell(wlabel); } } } catch (Exception e) { e.printStackTrace(); } } // 添加标题样式 private void addColumNameToWsheet(jxl.write.WritableSheet wsheet) throws RowsExceededException, WriteException { // 设置excel标题 jxl.write.WritableFont wfont = getFont(); if (null == wfont) { wfont = new WritableFont(WritableFont.ARIAL, WritableFont.DEFAULT_POINT_SIZE, WritableFont.BOLD); } jxl.write.WritableCellFormat wcfFC = getFormat(); if (null == wcfFC) { wcfFC = new jxl.write.WritableCellFormat(wfont); try { wcfFC.setWrap(true);// 自动换行 wcfFC.setAlignment(Alignment.CENTRE); wcfFC.setVerticalAlignment(VerticalAlignment.CENTRE);// 设置对齐方式 } catch (WriteException e) { e.printStackTrace(); } } jxl.write.Label wlabel1 = null; String[] columNames = columnNames; if (null == columNames) return; int colSize = columNames.length; Integer[] colsWidth = columnWidths; if (null == colsWidth) { colsWidth = new Integer[colSize]; for (int i = 0; i < colSize; i++) { colsWidth[i] = 20; } } int temp = 0; String colName = null; for (int i = 0; i < colSize; i++) { colName = columNames[i]; if (null == colName || "".equals(colName)) colName = ""; wlabel1 = new jxl.write.Label(i, 0, colName, wcfFC); wsheet.addCell(wlabel1); temp = colsWidth[i].intValue(); // 默认设置列宽 temp = temp == 0 ? 20 : temp; wsheet.setColumnView(i, temp); } } // 设置格式 private WritableCellFormat getFormat() { jxl.write.WritableFont wfont = getFont(); jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat( wfont); try { wcfFC.setWrap(true); wcfFC.setAlignment(Alignment.CENTRE); wcfFC.setVerticalAlignment(VerticalAlignment.CENTRE); } catch (WriteException e) { e.printStackTrace(); } return wcfFC; } // 设置字体 private WritableFont getFont() { return new WritableFont(WritableFont.ARIAL, WritableFont.DEFAULT_POINT_SIZE, WritableFont.BOLD); } }
1.3.3. poi返回excel
package com.loushi135.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.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.springframework.web.servlet.view.document.AbstractExcelView; import com.loushi135.model.User; public class UserListPoiExcelView extends AbstractExcelView { @Override protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { String fileName = "用户列表excel.xls"; // 设置response方式,使执行此controller时候自动出现下载页面,而非直接使用excel打开 response.setContentType("APPLICATION/OCTET-STREAM"); response.setHeader("Content-Disposition", "inline; filename="+new String(fileName.getBytes(),"iso8859-1")); List<User> userList = (List<User>) model.get("userList"); // 产生Excel表头 HSSFSheet sheet = workbook.createSheet("用户列表"); HSSFRow header = sheet.createRow(0); // 第0行 // 产生标题列 header.createCell((short) 0).setCellValue("name"); header.createCell((short) 1).setCellValue("password"); HSSFCellStyle cellStyle = workbook.createCellStyle(); // 填充数据 int rowNum = 1; for (User user:userList) { HSSFRow row = sheet.createRow(rowNum++); row.createCell((short) 0) .setCellValue(user.getName().toString()); row.createCell((short) 1).setCellValue(user.getPassword()); } // // 列总和计算 // HSSFRow row = sheet.createRow(rowNum); // row.createCell((short) 0).setCellValue("TOTAL:"); // String formual = "SUM(D2:D" + rowNum + ")"; // D2到D[rowNum]单元格起(count数据) // row.createCell((short) 3).setCellFormula(formual); } }
1.3.4. 返回pdf视图
package com.loushi135.view; import java.awt.Color; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.view.document.AbstractPdfView; import com.loushi135.model.User; import com.lowagie.text.Document; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.PdfWriter; public class UserListPdfView extends AbstractPdfView { @Override protected void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer, HttpServletRequest request, HttpServletResponse response) throws Exception { String fileName = "用户列表pdf.pdf"; // 设置response方式,使执行此controller时候自动出现下载页面,而非直接使用excel打开 response.setContentType("APPLICATION/OCTET-STREAM"); response.setHeader("Content-Disposition", "inline; filename="+new String(fileName.getBytes(),"iso8859-1")); List<User> userList = (List<User>) model.get("userList"); //显示中文 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); com.lowagie.text.Font FontChinese = new com.lowagie.text.Font(bfChinese, 12, com.lowagie.text.Font.NORMAL ); //创建一个有2列的表格 PdfPTable table = new PdfPTable(2); //定义一个表格单元 PdfPCell cell = new PdfPCell(new Paragraph("header with colspan 2")); //定义一个表格单元的跨度 cell.setColspan(2); //定义单元格的背景颜色 cell.setBackgroundColor(new Color(0xC0, 0xC0, 0xC0)); table.addCell(cell); PdfPCell headName = new PdfPCell(new Paragraph("姓名",FontChinese)); //定义单元格的框颜色 headName.setBorderColor(new Color(255, 0, 0)); PdfPCell headPassword = new PdfPCell(new Paragraph("密码",FontChinese)); headPassword.setBorderColor(new Color(255, 0, 0)); table.addCell(headName); table.addCell(headPassword); for (User user:userList) { PdfPCell name = new PdfPCell(new Paragraph(user.getName(),FontChinese)); PdfPCell password = new PdfPCell(new Paragraph(user.getPassword(),FontChinese)); table.addCell(name); table.addCell(password); } document.add(table); } }
1.3.5. 测试jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>视图</title> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.8.1.js"></script> <script type="text/javascript"> var _ctx="${pageContext.request.contextPath}"; $(document).ready(function(){ $("#json").click(function(event){ $.post( _ctx+"/user/getJson.do?content=json",//请求使用content=?来实现restful风格,来选择进入什么视图 {}, function(data){ var jsonData = data.jsonData; var message = ""; $(jsonData).each(function(i,item){//解析json message +=" 用户名:"+item.name+" 密码:"+item.password; }); alert(message); }, 'json' ); }); $("#xml").click(function(event){ $.post( _ctx+"/user/getXml.do?content=xml", {}, function(data){ var message = ""; $(data).find("User").each(function(i,item){//解析xml var name = $(item).children('name').text(); var password = $(item).children('password').text(); message +=" 用户名:"+name+" 密码:"+password; }); alert(message); }, 'xml' ); }); }); </script> </head> <body> <input type="button" value="请求返回json" id="json"/> <br/> <input type="button" value="请求返回xml" id="xml"/> <br> <input type="button" value="请求jxl返回excel" id="jxlExcel" onclick="location='${pageContext.request.contextPath}/user/getExcel.do'"/> <br/> <input type="button" value="请求poi返回excel" id="poiExcel" onclick="location='${pageContext.request.contextPath}/user/getPoiExcel.do'"/> <br/> <input type="button" value="请求返回pdf" id="pdf" onclick="location='${pageContext.request.contextPath}/user/getPdf.do'"/> <br/> <input type="button" value="请求返回模板" id="template"/> </body> </html>
通过http://localhost:8080/SpringMvcHelloWorld/user/userIndex.do 进入 userIndex.jsp
相关文章推荐
- 混合视图技术--ContentNegotiatingViewResolver
- SpringMVC 使用ContentNegotiatingViewResolver整合多种视图解析器
- spring mvc ContentNegotiatingViewResolver 根据路径后缀,选择不同视图
- SpringMVC ContentNegotiatingViewResolver -- 根据请求资源名选择视图
- ContentNegotiatingViewResolver spring REST中的内容协商(同一资源,多种展现:xml,json,html)
- Spring mvc 视图解析器 ContentNegotiatingViewResolver 源码分析
- Spring mvc 视图解析器 ContentNegotiatingViewResolver 源码分析
- SpringMVC ContentNegotiatingViewResolver -- 根据请求资源名选择视图
- Spring mvc ContentNegotiatingViewResolver 根据路径后缀,选择不同视图
- Spring mvc 视图解析器 ContentNegotiatingViewResolver 源码分析
- spring-freemarker.xml 视图解析器 ContentNegotiatingViewResolver 源码分析
- Spring MVC-ContentNegotiatingViewResolver 多视图返回
- ContentNegotiatingViewResolver - 内容协商视图解析器
- Spring mvc 视图解析器 ContentNegotiatingViewResolver 源码分析
- spring-mvc多视图解析配置实例 ContentNegotiatingViewResolver
- spring mvc4.2 ContentNegotiatingViewResolver 根据路径后缀,选择不同视图
- SpringMVC之ContentNegotiatingViewResolver实现根据请求资源名选择视图
- Spring mvc 视图解析器 ContentNegotiatingViewResolver 源码分析
- ContentNegotiatingViewResolver spring REST中的内容协商(同一资源,多种展现:xml,json,html)
- SpringMVC ContentNegotiatingViewResolver -- 根据请求资源名选择视图