4,spring MVC的視圖
Controller得到模型數據之后,通過視圖解析器生成視圖,渲染發送給用戶,用戶就看到了結果。
視圖:view接口,來個源碼查看;它由視圖解析器實例化,是無狀態的,所以線程安全。
spring mvc提供是視圖種類如圖所示,根據需要選擇合適的視圖:
視圖解析器:值提供一個把視圖名稱,結合本地化得到視圖實例的方法;
spring mvc提供的具體視圖解析器有,除去兩個抽象的,一共有14個;用戶可選擇多個視圖解析器,通過orderNo指定優先級,默認的ContenNegotiatingViewResolver優先級最高,InternalResourceViewResolver,XsltViewResolver優先級最低;
下面分別對常用的視圖舉例,記錄配置和使用方法:
Jsp和JStL的配置和使用方法:
jsp頁面的寫法:這里用到了三個標簽庫,還有國際化信息:
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@taglib prefix="fm" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <c:set var="ctx" value="${pageContext.request.contextPath}"/> <html> <head> <title>${title}</title> </head> <body> <h1>${title}</h1> <form:form modelAttribute="account" method="post" action="${ctx}/account/${action}"> <table width="100%" border="1px"> <thead> <tr> <td colspan="2"></td> </tr> </thead> <tr> <td><fm:message key="account.username"/> </td> <td> <form:errors path="userName" cssStyle="color: red;font: bolder;"/> <form:input path="userName" size="50" htmlEscape="true"/> </td> </tr> <tr> <td><spring:message code="account.password"/></td> <td> <form:errors path="password" cssStyle="color: red;font: bolder;"/> <form:password path="password" size="50" htmlEscape="true"/> </td> </tr> <tr> <td>昵稱</td> <td> <form:errors path="nickName" cssStyle="color: red;font: bolder;"/> <form:input path="nickName" size="50" htmlEscape="true"/> </td> </tr> <tr> <td><fm:message key="account.birthday"/></td> <td> <form:errors path="birthday" cssStyle="color: red;font: bolder;"/> <form:input path="birthday" size="50" htmlEscape="true"/> </td> </tr> <%--<tr>--%> <%--<td>有效期</td>--%> <%--<td>--%> <%--<form:errors path="validateTime" cssStyle="color: red;font: bolder;"/>--%> <%--<form:input path="validateTime" size="50" htmlEscape="true"/>--%> <%--</td>--%> <%--</tr>--%> <tr> <td><input type="submit" value="注冊"/></td> <td><input type="reset" value="重置"/></td> </tr> </table> </form:form> </body> </html>
關於spring提供的form標簽,如果是列表選擇,一般帶一個隱藏的字段,字段名是選擇標簽的名稱前面加個下划線,保證服務器表單對象和頁面表單組件數據一致;
Freemarker模版視圖:
首先看配置:
然后是使用了spring提供的宏的一個簡單模版:
<#import "spring.ftl" as spring /> <html> <head> <title>${title}</title> </head> <body> <table width="100%" border="1px;"> <#list accountList as account> <tr> <td>${account_index}</td> <td>${account[0]}</td> <td>${account[1]}</td> <td>${account[2]}</td> </tr> </#list> </table> </body> </html>
pdf:配置方法:
生成的視圖類:
package com.lfc.sh.web.sp.view; import com.google.common.base.Charsets; import com.lfc.sh.web.sp.util.AppConstant; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Table; import com.lowagie.text.pdf.BaseFont; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.document.AbstractPdfView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.util.List; import java.util.Map; public class UserListPdfView extends AbstractPdfView { @Override protected void buildPdfDocument(Map<String, Object> model, com.lowagie.text.Document document, com.lowagie.text.pdf.PdfWriter writer, HttpServletRequest request, HttpServletResponse response) throws Exception { String fileName = new String("用戶列表".getBytes(), Charsets.ISO_8859_1); response.setHeader(AppConstant.RESPONSE_HEADER, "inline;filename=" + fileName); Table table = new Table(5); table.setWidth(100); table.setBorder(1); table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER); table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE); Font font = new Font(BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false), 12, Font.BOLD, Color.BLACK); ModelAndView modelAndView= (ModelAndView) model.get("modelAndView"); List<Object[]> accountList = (List<Object[]>)modelAndView.getModel().get("accountList"); if(accountList!=null&&!accountList.isEmpty()) for (Object[] account : accountList) { table.addCell(account[0].toString()); table.addCell(account[3].toString()); table.addCell(account[4].toString()); table.addCell(account[2].toString()); table.addCell(account[1].toString()); } document.addTitle("用戶列表"); document.add(table); } }
效果:
json:配置方式
controller的寫法:
最終效果:
xls:配置方法:
<bean id="userListXls" class="com.lfc.sh.web.sp.view.UserListXlsView"></bean>
實現方法,引入poi;
package com.lfc.sh.web.sp.view; import com.google.common.base.Charsets; import com.lfc.sh.web.sp.util.AppConstant; 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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; /** * Company: Copyright© 2009 www.7road.com All rights reserved. * com.lfc.sh.web.sp.view * Create Date: 13-11-19 下午12:14 * Note:一個xls的視圖 */ public class UserListXlsView extends AbstractExcelView { @Override protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { String fileName = new String("用戶列表".getBytes(), Charsets.ISO_8859_1); response.setHeader(AppConstant.RESPONSE_HEADER, "inline;filename=" + fileName); HSSFSheet sheet=workbook.createSheet("用戶列表"); HSSFRow head=sheet.createRow(0); head.createCell(0).setCellValue("編號"); head.createCell(1).setCellValue("密碼"); head.createCell(2).setCellValue("昵稱"); head.createCell(3).setCellValue("用戶名"); head.createCell(4).setCellValue("生日"); List<Object[]> accountList= (List<Object[]>) model.get("accountList"); int rowNum=1; for(Object[] account:accountList) { HSSFRow row=sheet.createRow(rowNum); rowNum++; row.createCell(0).setCellValue(account[0].toString()); row.createCell(1).setCellValue(account[3].toString()); row.createCell(2).setCellValue(account[2].toString()); row.createCell(3).setCellValue(account[4].toString()); row.createCell(4).setCellValue(account[5].toString()); } } }
RessourceBoundleViewResolver,不同的地區用戶提供不同類型的視圖;
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="/i18n/views"/>
</bean>
/account/list.(class)=org.springframework.web.servlet.view.InternalResourceViewResolver
內容協商視圖:ContentNegotiatingViewResolver
配置方式:
<property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> <property name="contentType" value="text/html;charset=UTF-8"/> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="/i18n/content"/> <property name="cacheSeconds" value="0"/> <property name="defaultEncoding" value="UTF-8"/> </bean> <!-- 定義無Controller的path<->view直接映射 --> <!--<mvc:view-controller path="/" view-name="redirect:/task"/>--> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order" value="3"/> </bean> <bean id="userListPdf" class="com.lfc.sh.web.sp.view.UserListPdfView"></bean> <bean id="userListJson" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> <property name="prettyPrint" value="true"/> <property name="renderedAttributes" value="accountList"/> </bean> <bean id="userListXls" class="com.lfc.sh.web.sp.view.UserListXlsView"></bean> <!--<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">--> <!--<property name="basename" value="/i18n/views"/>--> <!--</bean>--> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="order" value="0"/> <property name="defaultContentType" value="text/html"/> <property name="ignoreAcceptHeader" value="true"/> <property name="favorParameter" value="true"/> <property name="favorPathExtension" value="false"/> <property name="parameterName" value="content"/> <property name="mediaTypes"> <map> <entry key="html" value="text/html"/> <entry key="json" value="application/json"/> </map> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"></bean> </list> </property> </bean>
效果:
//todo
5,spring MVC的本地化解析,文件上傳,靜態資源處理,攔截器,異常處理等
6,小結