spring mvc 打印HTML,Spring4 MVC ContentNegotiatingViewResolver多种输出格式实例

本文介绍了如何使用Spring MVC的ContentNegotiatingViewResolver来根据请求的媒体类型(如文件扩展名、URL参数或接受头)选择合适的视图。配置了XML、JSON、PDF和XLS输出的支持,使用了Jackson和iText等库。通过创建不同的视图解析器,实现了XML、JSON、PDF和XLS以及HTML输出。并给出了相应的配置类、控制器和初始化类的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ContentNegotiatingViewResolver是 ViewResolver 使用所请求的媒体类型的一个实现(基于文件类型扩展,输出格式URL参数指定类型或接受报头)来选择一个合适的视图一个请求。ContentNegotiatingViewResolver本身并不解决视图,只不表示为其他的 ViewResolver,您可以配置来处理特定的视图(XML,JSON,PDF,XLS,HTML,..)。

这里需要使用到以下技术:

Spring 4.0.6.RELEASE

jackson-databind 2.4.1.3

jackson-annotations 2.4.1

lowagie itext 4.2.1

Apache POI 3.10-beta2

Maven 3

JDK 1.6

Tomcat 7.0.54

Eclipse JUNO Service Release 2

我们现在就开始!

第1步:创建目录结构

以下将是本实例的最终目录结构:

46001fa3c18ee0e528d7d1361ba1f230.png

我们将使用Spring Java配置(注释)。现在,让我们来添加/更新上述项目结构中提到的内容。

第2步:用所需的依赖更新 pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"

xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

4.0.0

com.yiibai.springmvc

ContentNegotiatingViewResolverwar

1.0.0

Spring4MVCContentNegotiatingViewResolverExample

4.0.6.RELEASE

org.springframework

spring-core

${springframework.version}

org.springframework

spring-web

${springframework.version}

org.springframework

spring-webmvc

${springframework.version}

org.springframework

spring-oxm

${springframework.version}

com.fasterxml.jackson.core

jackson-databind

2.4.1.3

com.fasterxml.jackson.core

jackson-annotations

2.4.1

com.lowagie

itext

4.2.1

org.apache.poi

poi

3.10-beta2

javax.servlet

javax.servlet-api

3.1.0

javax.servlet

jstl

1.2

javax.servlet.jsp

javax.servlet.jsp-api

2.3.1

org.apache.maven.plugins

maven-war-plugin

2.4

src/main/webapp

ContentNegotiatingViewResolverfalse

ContentNegotiatingViewResolver

上面解析 PDF 的依赖库有点问题,可修改为以下测试构建就没有问题:

com.lowagie

itext

2.1.7

compile

spring-oxm是为了支持XML输出生成(使用JAXB2)。 jackson-databind &jackson-annotations 提供JSON输出支持。iText的提供PDF生成库,支持PDF输出。 Apache POI将有助于产生XLS输出格式。

第3步:创建Spring配置文件类

com.yiibai.springmvc.configuration.AppConfig

package com.yiibai.springmvc.configuration;

import java.util.ArrayList;

import java.util.List;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.MediaType;

import org.springframework.oxm.jaxb.Jaxb2Marshaller;

import org.springframework.web.accept.ContentNegotiationManager;

import org.springframework.web.servlet.ViewResolver;

import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;

import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;

import org.springframework.web.servlet.view.InternalResourceViewResolver;

import org.springframework.web.servlet.view.JstlView;

import com.yiibai.springmvc.model.Pizza;

import com.yiibai.springmvc.viewresolver.ExcelViewResolver;

import com.yiibai.springmvc.viewresolver.JsonViewResolver;

import com.yiibai.springmvc.viewresolver.Jaxb2MarshallingXmlViewResolver;

import com.yiibai.springmvc.viewresolver.PdfViewResolver;

@Configuration

@EnableWebMvc

@ComponentScan(basePackages = "com.yiibai.springmvc")

public class AppConfig extends WebMvcConfigurerAdapter {

/*

* Configure ContentNegotiationManager

*/

@Override

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

configurer.ignoreAcceptHeader(true).defaultContentType(

MediaType.TEXT_HTML);

}

/*

* Configure ContentNegotiatingViewResolver

*/

@Bean

public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {

ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();

resolver.setContentNegotiationManager(manager);

// Define all possible view resolvers

List resolvers = new ArrayList();

resolvers.add(jaxb2MarshallingXmlViewResolver());

resolvers.add(jsonViewResolver());

resolvers.add(jspViewResolver());

resolvers.add(pdfViewResolver());

resolvers.add(excelViewResolver());

resolver.setViewResolvers(resolvers);

return resolver;

}

/*

* Configure View resolver to provide XML output Uses JAXB2 marshaller to

* marshall/unmarshall POJO's (with JAXB annotations) to XML

*/

@Bean

public ViewResolver jaxb2MarshallingXmlViewResolver() {

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();

marshaller.setClassesToBeBound(Pizza.class);

return new Jaxb2MarshallingXmlViewResolver(marshaller);

}

/*

* Configure View resolver to provide JSON output using JACKSON library to

* convert object in JSON format.

*/

@Bean

public ViewResolver jsonViewResolver() {

return new JsonViewResolver();

}

/*

* Configure View resolver to provide PDF output using lowagie pdf library to

* generate PDF output for an object content

*/

@Bean

public ViewResolver pdfViewResolver() {

return new PdfViewResolver();

}

/*

* Configure View resolver to provide XLS output using Apache POI library to

* generate XLS output for an object content

*/

@Bean

public ViewResolver excelViewResolver() {

return new ExcelViewResolver();

}

/*

* Configure View resolver to provide HTML output This is the default format

* in absence of any type suffix.

*/

@Bean

public ViewResolver jspViewResolver() {

InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

viewResolver.setViewClass(JstlView.class);

viewResolver.setPrefix("/WEB-INF/views/");

viewResolver.setSuffix(".jsp");

return viewResolver;

}

}

让我们来讨论说明上面的类的详细信息:

第一步是建立它用于通过委托给ContentNegotiationManager,以确定所请求的媒体类型的请求是 ContentNegotiationStrategy 列表的一个实例。默认情况下PathExtensionContentNegotiationStrategy被查询(使用URL扩展名,例如. .xls, .pdf,.json.),接着ParameterContentNegotiationStrategy(使用请求参数 ‘format=xls’,例如),其次是HeaderContentNegotiationStrategy(使用HTTP接受头)。

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

configurer.ignoreAcceptHeader(true).defaultContentType(

MediaType.TEXT_HTML);

}

在我们的例子中,我们将使用URL扩展名来帮助确定媒体类型。此外,我们还设置默认介质类型TEXT_HTML在没有文件扩展名或当文件类型是未知时,这意味着JSP视图解析器将被用于在没有[known] URL扩展中。

下面是 pizza.jsp 默认使用JSP视图解析器内容

Pizza JSP View
NAMEFlavorToppings
${pizza.name}${pizza.flavor}

下一步是配置 ContentNegotaionViewResolver 本身,

public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {

ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();

resolver.setContentNegotiationManager(manager);

// Define all possible view resolvers

List resolvers = new ArrayList();

resolvers.add(jaxb2MarshallingXmlViewResolver());

resolvers.add(jsonViewResolver());

resolvers.add(jspViewResolver());

resolvers.add(pdfViewResolver());

resolvers.add(excelViewResolver());

resolver.setViewResolvers(resolvers);

return resolver;

}

我们需要设置 ContentNegotiationManager由Spring 注入,和为每一个应用程序可能会产生输出格式设置不同的解析器,。

最后,我们已经创建了不同的视图解析器以对 XML,JSON,PDF,XLS 和 HTML 输出,我们将在节中讨论。

第4步:创建不同的视图解析器

现在,让我们创建塔实际视图解析器

XML View Resolver:

这个视图解析器依赖于JAXB2编组/解组产生XML输出。domain类需要和JAXB2注释进行注释。

com.yiibai.springmvc.viewresolver.Jaxb2MarshallingXmlViewResolver

package com.yiiibai.springmvc.viewresolver;

import java.util.Locale;

import org.springframework.oxm.Marshaller;

import org.springframework.web.servlet.View;

import org.springframework.web.servlet.ViewResolver;

import org.springframework.web.servlet.view.xml.MarshallingView;

public class Jaxb2MarshallingXmlViewResolver implements ViewResolver {

private Marshaller marshaller;

public Jaxb2MarshallingXmlViewResolver(Marshaller marshaller) {

this.marshaller = marshaller;

}

@Override

public View resolveViewName(String viewName, Locale locale) throws Exception {

MarshallingView view = new MarshallingView();

view.setMarshaller(marshaller);

return view;

}

}

下面是域对象(标注了标准的XML注释)在我们的例子:

com.yiibai.springmvc.model.Pizza

package com.yiibai.springmvc.model;

import java.util.ArrayList;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "pizza")

public class Pizza {

private String name;

private String flavor;

private List toppings = new ArrayList();

public Pizza(){

}

public Pizza(String name){

this.name = name;

this.flavor = "spicy";

this.toppings.add("Cheese");

this.toppings.add("bakon");

}

@XmlElement

public void setName(String name) {

this.name = name;

}

public String getName() {

return name;

}

@XmlElement

public void setFlavor(String flavor) {

this.flavor = flavor;

}

public String getFlavor() {

return flavor;

}

public List getToppings() {

return toppings;

}

@XmlElement

public void setToppings(List toppings) {

this.toppings = toppings;

}

}

JSON View Resolver:

这个视图解析器是使用 Spring MappingJackson2JsonView 为了将 POJO 对象转换成 JSON 视图。

com.yiibai.springmvc.viewresolver.JsonViewResolver

package com.yiibai.springmvc.viewresolver;

import java.util.Locale;

import org.springframework.web.servlet.View;

import org.springframework.web.servlet.ViewResolver;

import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

public class JsonViewResolver implements ViewResolver{

@Override

public View resolveViewName(String viewName, Locale locale) throws Exception {

MappingJackson2JsonView view = new MappingJackson2JsonView();

view.setPrettyPrint(true);

return view;

}

}

PDF View Resolver:

这个视图解析器使用lowagie iText库实际生成PDF输出。还要注意的是实际的视图,从Spring AbstractPdfView 内部使用 lowagie iText 库扩展。

com.yiibai.springmvc.viewresolver.PdfView

package com.yiibai.springmvc.viewresolver;

import java.awt.Color;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.view.document.AbstractPdfView;

import com.lowagie.text.Document;

import com.lowagie.text.Element;

import com.lowagie.text.pdf.PdfPTable;

import com.lowagie.text.pdf.PdfWriter;

import com.yiibai.springmvc.model.Pizza;

public class PdfView extends AbstractPdfView {

@Override

protected void buildPdfDocument(Map model,

Document document, PdfWriter writer, HttpServletRequest request,

HttpServletResponse response) throws Exception {

Pizza pizza = (Pizza) model.get("pizza");

PdfPTable table = new PdfPTable(3);

table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);

table.getDefaultCell().setBackgroundColor(Color.lightGray);

table.addCell("Name");

table.addCell("Flavor");

table.addCell("Toppings");

table.addCell(pizza.getName());

table.addCell(pizza.getFlavor());

StringBuffer toppings = new StringBuffer("");

for (String topping : pizza.getToppings()) {

toppings.append(topping);

toppings.append(" ");

}

table.addCell(toppings.toString());

document.add(table);

}

}

com.yiibai.springmvc.viewresolver.PdfViewResolver类代码:

package com.yiibai.springmvc.viewresolver;

import java.util.Locale;

import org.springframework.web.servlet.View;

import org.springframework.web.servlet.ViewResolver;

public class PdfViewResolver implements ViewResolver{

@Override

public View resolveViewName(String viewName, Locale locale) throws Exception {

PdfView view = new PdfView();

return view;

}

}

XLS View Resolver:

这个视图解析器是使用Apache POI库实际生成 Microsoft XLS输出。还要注意的是实际的视图,从Spring AbstractExcelView 内部使用 Apache POI库扩展。

com.yiibai.springmvc.viewresolver.ExcelView

package com.yiibai.springmvc.viewresolver;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.CellStyle;

import org.apache.poi.ss.usermodel.IndexedColors;

import org.apache.poi.ss.usermodel.Row;

import org.apache.poi.ss.usermodel.Sheet;

import org.springframework.web.servlet.view.document.AbstractExcelView;

import com.yiibai.springmvc.model.Pizza;

public class ExcelView extends AbstractExcelView {

@Override

protected void buildExcelDocument(Map model,

HSSFWorkbook workbook, HttpServletRequest request,

HttpServletResponse response) throws Exception {

Pizza pizza = (Pizza) model.get("pizza");

Sheet sheet = workbook.createSheet("sheet 1");

CellStyle style = workbook.createCellStyle();

style.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.index);

style.setFillPattern(CellStyle.SOLID_FOREGROUND);

style.setAlignment(CellStyle.ALIGN_CENTER);

Row row = null;

Cell cell = null;

int rowCount = 0;

int colCount = 0;

// Create header cells

row = sheet.createRow(rowCount++);

cell = row.createCell(colCount++);

cell.setCellStyle(style);

cell.setCellValue("Name");

cell = row.createCell(colCount++);

cell.setCellStyle(style);

cell.setCellValue("Flavor");

cell = row.createCell(colCount++);

cell.setCellStyle(style);

cell.setCellValue("Toppings");

// Create data cells

row = sheet.createRow(rowCount++);

colCount = 0;

row.createCell(colCount++).setCellValue(pizza.getName());

row.createCell(colCount++).setCellValue(pizza.getFlavor());

StringBuffer toppings = new StringBuffer("");

for (String topping : pizza.getToppings()) {

toppings.append(topping);

toppings.append(" ");

}

row.createCell(colCount++).setCellValue(toppings.toString());

for (int i = 0; i < 3; i++)

sheet.autoSizeColumn(i, true);

}

}

com.yiibai.springmvc.viewresolver.ExcelViewResolver

package com.yiibai.springmvc.viewresolver;

import java.util.Locale;

import org.springframework.web.servlet.View;

import org.springframework.web.servlet.ViewResolver;

public class ExcelViewResolver implements ViewResolver{

@Override

public View resolveViewName(String viewName, Locale locale) throws Exception {

ExcelView view = new ExcelView();

return view;

}

}

这是所有 ContentNegotaingViewResolver 需要的配置。

完成这个例子并让它可以运行,让我们添加缺少 Spring MVC 配置。

第5步:创建控制器类

下面是一个简单的基于REST的控制器作为我们的示例。

com.yiibai.springmvc.controller.AppController

package com.yiibai.springmvc.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import com.yiibai.springmvc.model.Pizza;

@Controller

public class AppController {

@RequestMapping(value="/pizzavalley/{pizzaName}", method = RequestMethod.GET)

public String getPizza(@PathVariable String pizzaName, ModelMap model) {

Pizza pizza = new Pizza(pizzaName);

model.addAttribute("pizza", pizza);

return "pizza";

}

}

第6步:创建初始化类

添加一个初始化类实现WebApplicationInitializer如下图所示(在这种情况下,作为替代在 web.xml 中定义的任何 Spring 配置)。在Servlet 3.0的容器启动时,这个类会被加载并实例及其 onStartup方法将通过servlet容器调用。

com.yiibai.springmvc.configuration.AppInitializer

package com.yiibai.springmvc.configuration;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;

import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import org.springframework.web.servlet.DispatcherServlet;

public class AppInitializer implements WebApplicationInitializer {

public void onStartup(ServletContext container) throws ServletException {

AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();

ctx.register(AppConfig.class);

ctx.setServletContext(container);

ServletRegistration.Dynamic servlet = container.addServlet(

"dispatcher", new DispatcherServlet(ctx));

servlet.setLoadOnStartup(1);

servlet.addMapping("/");

}

}

更新:请注意,上面的类可以写成更加简洁[和它的首选方式],通过扩展 AbstractAnnotationConfigDispatcherServletInitializer 基类,如下所示:

package com.yiibai.springmvc.configuration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override

protected Class>[] getRootConfigClasses() {

return new Class[] { AppConfig.class };

}

@Override

protected Class>[] getServletConfigClasses() {

return null;

}

@Override

protected String[] getServletMappings() {

return new String[] { "/" };

}

}

第7步:构建和部署应用程序

现在构建 war(通过Eclipse或Maven [ mvn clean install])。部署 war 到Servlet3.0容器。

1df9f94331cc70c3d8fcac20f20a4f81.png

03ee46d6d2980dc71f69d229bab6df07.png

fe96c9791f610f24952523beccbcf9e2.png

8346f0f8740b903b3551f0eab00e4017.png

fae73111b68a84bc9ad83842e4c234e8.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值