Spring Content Negotiation

By Arvind Rai, June 24, 2019
This page will walk through Spring content negotiation example with AbstractExcelView, AbstractPdfView, MappingJackson2JsonView and MappingJackson2XmlView. Content Negotiation is determining view on the basis of media type of user request. Media types can be determined by file extension, "Accept" header or a request parameter. First priority is file extension then "Accept" header etc. There will also be a fall back for default content type. In our example the user will have only one URL but different file extension in URL. We are handling here .xls, .pdf, .json, .xml and .html. If no extension is provided default view will be as html. AbstractExcelView and AbstractPdfView will handle view for excel and PDF respectively. MappingJackson2JsonView and MappingJackson2XmlView will handle view for JSON and XML respectively.

Software Used

Find the software used in our demo.
1. Java 7
2. Spring 4.1.6
3. Gradle
4. Eclipse
5. Tomcat 8

Project Structure in Eclipse

Find the project structure in eclipse.
Spring 4 Content Negotiation Example with AbstractExcelView, AbstractPdfView, MappingJackson2JsonView and MappingJackson2XmlView

build.gradle

Find the build file.
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
archivesBaseName = 'Spring4'
version = '1' 
repositories {
    mavenCentral()
}
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web:1.2.3.RELEASE'
    compile 'com.lowagie:itext:4.2.1'
    compile 'org.apache.poi:poi:3.13'
    compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.6.2'
    compile 'org.codehaus.woodstox:woodstox-core-asl:4.4.1'
    compile 'jstl:jstl:1.2'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.2.3.RELEASE'
}  

JavaConfig: Define configureContentNegotiation() and configureViewResolvers()

Find the JavaConfig which is defining configureContentNegotiation() and configureViewResolvers() methods.
AppConfiguration.java
package com.concretepage.config;  
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.web.servlet.view.xml.MappingJackson2XmlView;
import com.concretepage.view.ContentExcelView;
import com.concretepage.view.ContentPdfView;
@Configuration 
@ComponentScan("com.concretepage") 
@EnableWebMvc
public class AppConfiguration extends WebMvcConfigurerAdapter  {  
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
	configurer.ignoreUnknownPathExtensions(false).defaultContentType(MediaType.TEXT_HTML);
    }
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
    	MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
    	jsonView.setPrettyPrint(true);
    	MappingJackson2XmlView xmlView = new MappingJackson2XmlView();
    	xmlView.setPrettyPrint(true);
        registry.enableContentNegotiation(jsonView, xmlView, 
        		new ContentExcelView(), new ContentPdfView());
        registry.jsp("/WEB-INF/view/", ".jsp");
    }
} 
Initializer.java
package com.concretepage.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class Initializer implements WebApplicationInitializer {
	public void onStartup(ServletContext servletContext) throws ServletException {  
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();  
        ctx.register(AppConfiguration.class);  
        ctx.setServletContext(servletContext);    
        Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));  
        dynamic.addMapping("/");  
        dynamic.setLoadOnStartup(1);  
   }  
} 

AbstractExcelView for Excel

ContentExcelView.java
package com.concretepage.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.HSSFSheet;
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.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.web.servlet.view.document.AbstractExcelView;
import com.concretepage.bean.MyContent;
public class ContentExcelView extends AbstractExcelView {
	@Override
	protected void buildExcelDocument(Map<String, Object> model,
			HSSFWorkbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		HSSFSheet sheet = workbook.createSheet("My Content");
	    Row row = sheet.createRow(0);
	    CellStyle style = workbook.createCellStyle();
	    style.setFillBackgroundColor(IndexedColors.YELLOW.getIndex());
	    style.setFillPattern(CellStyle.ALIGN_FILL);
	    Font font = workbook.createFont();
            font.setColor(IndexedColors.RED.getIndex());
            style.setFont(font);
	    Cell cell1 = row.createCell(0);
	    cell1.setCellValue("ID");
	    cell1.setCellStyle(style);
	    Cell cell2 = row.createCell(1);
	    cell2.setCellValue("TITLE");
	    cell2.setCellStyle(style);
	    Cell cell3 = row.createCell(2);
	    cell3.setCellValue("DESCRIPTION");
	    cell3.setCellStyle(style);
	    Cell cell4 = row.createCell(3);
	    cell4.setCellValue("PUBDATE");
	    cell4.setCellStyle(style);
	    Cell cell5 = row.createCell(4);
	    cell5.setCellValue("LINK");
	    cell5.setCellStyle(style);
	    Object ob = model.get("contents");
	    if (ob instanceof List){
	        for(int i = 0; i < ((List<?>)ob).size(); i++){
	            Object feedObj = ((List<?>) ob).get(i);
	            MyContent myContent = (MyContent)feedObj;
	            row = sheet.createRow(i+1);
	    	    cell1 = row.createCell(0);
	    	    cell1.setCellValue(myContent.getId());
	    	    cell2 = row.createCell(1);
	    	    cell2.setCellValue(myContent.getTitle());
	    	    cell3 = row.createCell(2);
	    	    cell3.setCellValue(myContent.getDescription());
	    	    cell4 = row.createCell(3);
	    	    cell4.setCellValue(myContent.getPubDate());
	    	    cell5 = row.createCell(4);
	    	    cell5.setCellValue(myContent.getLink());
	        }
	   }
       }
} 

AbstractPdfView for PDF

ContentPdfView.java
package com.concretepage.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.concretepage.bean.MyContent;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
public class ContentPdfView extends AbstractPdfView{
	@Override
	protected void buildPdfMetadata(Map<String, Object> model, 
			Document document, HttpServletRequest request) {
		Rectangle rec = new Rectangle(600, 800);
		document.setPageSize(rec);
		document.setPageCount(1);
	}
	@Override
	protected void buildPdfDocument(Map<String, Object> model,
			Document document, PdfWriter writer, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
          PdfPTable table = new PdfPTable(5);
          table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
          table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
          table.getDefaultCell().setBackgroundColor(Color.CYAN);
	  Object ob = model.get("contents");
	  if (ob instanceof List){
	    for(int i = 0; i < ((List<?>)ob).size(); i++){
	            Object feedObj = ((List<?>) ob).get(i);
	            MyContent myContent = (MyContent)feedObj;
	            table.addCell(myContent.getId());
	            table.addCell(myContent.getTitle());
	            table.addCell(myContent.getDescription());
	            table.addCell(myContent.getPubDate().toString());
	            table.addCell(myContent.getLink());
	   }
	  }
          table.completeRow();
          document.add(table); 
	} 
} 

Bean

MyContent.java
package com.concretepage.bean;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Repository;
@Repository
public class MyContent {
	private String id;
	private String title;
	private String description;
	private Date pubDate;
	private String link;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public Date getPubDate() {
		return pubDate;
	}
	public void setPubDate(Date pubDate) {
		this.pubDate = pubDate;
	}
	public String getLink() {
		return link;
	}
	public void setLink(String link) {
		this.link = link;
	}
	public List<MyContent> createContent() {
		List<MyContent> feeds = new ArrayList<>();
		MyContent feed1 = new MyContent();
		feed1.setId("100");
		feed1.setTitle("Title one");
		feed1.setDescription("This is description one");
		feed1.setLink("http://www.urlone.com");
		feed1.setPubDate(new Date());
		feeds.add(feed1);
		
		MyContent feed2 = new MyContent();
		feed2.setId("200");
		feed2.setTitle("Title two");
		feed2.setDescription("This is description two");
		feed2.setLink("http://www.urltwo.com");
		feed2.setPubDate(new Date());
		feeds.add(feed2);
		return feeds;
	}
} 

MappingJackson2JsonView for JSON

For JSON content type, we will configure MappingJackson2JsonView in our JavaConfig creating its instance as below.
MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
jsonView.setPrettyPrint(true); 

MappingJackson2XmlView for XML

For XML content type, we will configure MappingJackson2XmlView in our JavaConfig creating its instance as below.
MappingJackson2XmlView xmlView = new MappingJackson2XmlView();
xmlView.setPrettyPrint(true); 

View for HTML

result.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<title>Spring 4 Content Negotiation Example</title> 
<body>
<table>
<c:forEach items="${contents}" var="element"> 
  <tr>
    <td>${element.id}</td>
    <td>${element.title}</td>
    <td>${element.description}</td>
    <td>${element.pubDate}</td>
    <td>${element.link}</td>    
  </tr>
</c:forEach> 
</table>
</body>
</html> 

Controller Class

ContentController.java
package com.concretepage.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.concretepage.bean.MyContent;
@Controller
public class ContentController {
	@Autowired
	private MyContent myContent;
	@RequestMapping(value="/content", method=RequestMethod.GET)
	public ModelAndView getContent() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("result");
		mav.addObject("contents", myContent.createContent());
		return mav;
	}
} 

Output

1. URL for Excel http://localhost:8080/Spring4-1/content.xls
Spring 4 Content Negotiation Example with AbstractExcelView, AbstractPdfView, MappingJackson2JsonView and MappingJackson2XmlView

2. URL for PDF http://localhost:8080/Spring4-1/content.pdf
Spring 4 Content Negotiation Example with AbstractExcelView, AbstractPdfView, MappingJackson2JsonView and MappingJackson2XmlView

3. URL for JSON http://localhost:8080/Spring4-1/content.json
Spring 4 Content Negotiation Example with AbstractExcelView, AbstractPdfView, MappingJackson2JsonView and MappingJackson2XmlView

4. URL for XML http://localhost:8080/Spring4-1/content.xml
Spring 4 Content Negotiation Example with AbstractExcelView, AbstractPdfView, MappingJackson2JsonView and MappingJackson2XmlView

5. URL for HTML http://localhost:8080/Spring4-1/content.html
or http://localhost:8080/Spring4-1/content
Spring 4 Content Negotiation Example with AbstractExcelView, AbstractPdfView, MappingJackson2JsonView and MappingJackson2XmlView

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us