混合多種視圖技術:ContentNegotiatingViewResolver

1. 混合多種視圖技術

1.1. 目的

同一資源,多種表述,允許你用同樣的內容數據來呈現不同的view

1.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 headerAccept

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 "userListExcelView";
}
/**
 * 返回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" οnclick="location='${pageContext.request.contextPath}/user/getExcel.do'"/>
     <br/>
     <input type="button" value="請求poi返回excel" id="poiExcel" οnclick="location='${pageContext.request.contextPath}/user/getPoiExcel.do'"/>
     <br/>
     <input type="button" value="請求返回pdf" id="pdf" οnclick="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



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章