By kswaughs | Sunday, April 10, 2016

Spring MVC PDF View Example

Spring MVC Framework has built in methods and components to render the output in many documents like PDF, EXCEL along with JSPs. In this example, we will see how to configure and develop our spring based application to allow users to download the web content in PDF document.

We have an online store application where the home page displays list of the phones available and allows user to choose a phone to get its details. After submission, price details are shown in the next page along with a download link to view the page in PDF format. Now, we will follow the below steps in developing this application.

1. Maven Dependencies

2. Define Controllers, Service & model classes

3. Define Custom PDF View

4. View Configuration

5. Servlet Configuration

6. JSPs implementation

1. Maven Dependencies

pom.xml
<dependencies>
   <!--Spring framework related jars-->
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.2.10.RELEASE</version>
   </dependency>
   <!--Itext jar for PDF generation-->
   <dependency>
      <groupId>com.lowagie</groupId>
      <artifactId>itext</artifactId>
      <version>2.1.7</version>
   </dependency>
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
   </dependency>
   <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
   </dependency>
</dependencies>

2. Define Controllers, Service & model classes

Create a Controller class to handle the requests based on the URL mappings.

PhoneController
package com.kswaughs.web.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.kswaughs.web.beans.Phone;
import com.kswaughs.web.service.PhoneService;

@Controller
@RequestMapping(value = "/phones")
@SessionAttributes("phone")
public class PhoneController {
    
    @Autowired
    PhoneService phoneSvc;
    
    @RequestMapping(value = "", method = RequestMethod.GET)
    public ModelAndView home() {
        
        List<Phone> phonesList = phoneSvc.getPhoneslist();
        
        ModelAndView mv = new ModelAndView("home", "phones",  phonesList);
        mv.addObject("phone", new Phone());
            
        return  mv;
    }
    
    @RequestMapping(value = "/details", method = RequestMethod.POST)
    public ModelAndView showPrice(@ModelAttribute("phone") Phone phone ) {
                
        phone = phoneSvc.getPhoneDetails(phone);
                
        return new ModelAndView("details", "phone", phone);
    }
        
    
    @RequestMapping(value = "/details/pdf", method = RequestMethod.GET)
    public ModelAndView showPriceInPDF(@ModelAttribute("phone") Phone phone ) {
                
        List<Phone> phonesList = phoneSvc.getPhoneslist();
        
        return new ModelAndView("pdfView", "phonesList",  phonesList);
    }
}

Create a Service class to process the requests.

PhoneService
package com.kswaughs.web.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.kswaughs.annotations.TrackResponse;
import com.kswaughs.web.beans.Phone;

@Service
public class PhoneService {
    
    public List<Phone> getPhoneslist() {
        
        List<Phone> phonesList = new ArrayList<Phone>();
        
        phonesList.add(buildPhone("1", "Samsung Galaxy Y"));
        phonesList.add(buildPhone("2", "Nokia Lumia"));
        phonesList.add(buildPhone("3", "Moto G"));
        phonesList.add(buildPhone("4", "Lenovo A 7000 white"));
        phonesList.add(buildPhone("5", "Sony XPeria"));
        
        return phonesList;
    }
    
    public Phone getPhoneDetails(Phone phone) {
                
        final String id = phone.getId();
        String price = null;
        if("1".equals(id)) {
            phone = buildPhone("1", "Samsung Galaxy Y");
            price = "10,000";
            
        } else if("2".equals(id)) {
            phone = buildPhone("2", "Nokia Lumia");
            price = "12,000";
        
        } else if("3".equals(id)) {
            phone = buildPhone("3", "Moto G");
            price = "14,000";
        
        } else if("4".equals(id)) {
            phone = buildPhone("4", "Lenovo A 7000 white");
            price = "9,800";
        
        } else if("5".equals(id)) {
            phone = buildPhone("5", "Sony XPeria");
            price = "23,000";
        }
        
        phone.setPrice(price);
        return phone;
        
    }
    
    private Phone buildPhone(String id, String name) {
        
        Phone phone = new Phone(id, name);
        return phone;
    }
    
}

Below is the Model class to hold phone details.

Phone
package com.kswaughs.web.beans;

public class Phone {
    
    private String id;
    
    private String name;
    
    private String price;
    
    public Phone() {
        
    }
    
    public Phone(String id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}

3. Define Custom PDF View Component

Create a new class that extends AbstractPdfView and override buildPdfDocument() method with data from session object.

PDFBuilder
package com.kswaughs.web.views;

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.stereotype.Component;
import org.springframework.web.servlet.view.document.AbstractPdfView;

import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import com.kswaughs.web.beans.Phone;

@Component
public class PDFBuilder extends AbstractPdfView {

    @Override
    protected void buildPdfDocument(Map<String, Object> model, Document doc,
            PdfWriter writer, HttpServletRequest req, HttpServletResponse resp)
            throws Exception {

        Phone ph = (Phone) req.getSession().getAttribute("phone");

        doc.add(new Paragraph(
                "Dear User, Following is the list of available phones in our shop."));

        List<Phone> phonesList = (List<Phone>) model.get("phonesList");

        PdfPTable table = new PdfPTable(2);
        table.setSpacingBefore(10);

        // define font for table header row
        Font font = FontFactory.getFont(FontFactory.HELVETICA);
        font.setColor(Color.WHITE);

        // define table header cell
        PdfPCell cell = new PdfPCell();
        cell.setBackgroundColor(Color.BLUE);
        cell.setPadding(5);

        cell.setPhrase(new Phrase("ID", font));
        table.addCell(cell);

        cell.setPhrase(new Phrase("Name", font));
        table.addCell(cell);

        for (Phone phone : phonesList) {
            table.addCell(phone.getId());
            table.addCell(phone.getName());
        }

        doc.add(table);
        
        doc.add(new Paragraph(
                "Please find the price details of phone you have selected."));

        Font priceTxtFont = new Font();
        priceTxtFont.setColor(Color.BLUE);
            
        doc.add(new Paragraph("Phone :" + ph.getName(), priceTxtFont));
        doc.add(new Paragraph("Price :" + ph.getPrice() + "Rs/-", priceTxtFont));

    }

}

4. View Configuration

Add below entry in 'views.properties' file which should be placed in src/main/resources folder. The view name 'pdfView' is mapped to PDFBuilder View component.

views.properties
pdfView.(class)=com.poc.web.views.PDFBuilder

Configure a new ViewResolver with this properties file in Java Configuration

SpringWebConfig
package com.kswaughs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.ResourceBundleViewResolver;

@EnableWebMvc 
@Configuration
@ComponentScan({ "com.kswaughs.web" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }
    
    @Bean
    public ViewResolver jspViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/jsps/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
    
    @Bean
    public ViewResolver resourceBundleViewResolver() {
        
        ResourceBundleViewResolver viewResolver = new ResourceBundleViewResolver();
        viewResolver.setBasename("views");
        viewResolver.setOrder(1);
        
        return viewResolver;
    }
        
}

5. Servlet Configuration

Create below servlet initialization class.

SpringWebInitializer
package com.kswaughs.servlet;

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

import com.kswaughs.config.SpringWebConfig;

public class SpringWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[] { SpringWebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[] {};
    }
    
}

6. JSPs implementation

Home page that displays the list of phones available and allows user to choose one.

home.jsp

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <head>
    <spring:url value="/resources/css/style.css" var="style" />
    <spring:url value="/phones/details" var="submiturl" />
    <link href="${style}" rel="stylesheet" />
    </head>
    <body>
    <div>
        <p>Welcome to Phones Store</p>
        <p>Choose your Phone below</p>
        <div>
        <form:form method="post" action="${submiturl}" commandName="phone">
        <c:forEach var="ph" items="${phones}">
            <div><form:radiobutton path="id" value="${ph.id}"/>${ph.name}</div>
        </c:forEach>
            <input type="submit"  value="submit"/>
        </form:form>
        </div>
    </div>
    </body>
</html>

Details page that displays the price details of selected phone.

details.jsp
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <head>
        <spring:url value="/resources/css/style.css" var="style" />
        <spring:url value="/phones/details/pdf" var="pdfLink" />
        <link href="${style}" rel="stylesheet" />
    </head>
    <body>
    <div>
        <p>Welcome to Phones Store</p>
        <p>Your phone details</p>
        <div>Phone : ${phone.name}</div>
        <div>Price : ${phone.price} Rs/<sub>-</sub></div>
    </div>
    <div>
        <a href="${pdfLink}">Click here to download in PDF.</a>
    </div>
    </body>
</html>

Testing the application

Home page

http://localhost:8080/spring_app/phones

Welcome to Phones Store
Choose your Phone below
Samsung Galaxy Y
Nokia Lumia
Moto G
Lenovo A 7000 white
Sony XPeria

Details page

http://localhost:8080/spring_app/phones/details

Welcome to Phones Store
Your phone details
Phone : Lenovo A 7000 white
Price : 9,800 Rs/-

On clicking the pdf download link, You will see below content in PDF file.

Recommend this on


6 comments:

  1. On the off chance that you need to deliver excellent books, utilize Kindle Previewer before distributing any digital book unlock pdf

    ReplyDelete
  2. Thats amazing to come across such a valuable post.Your blog helps for the beginners to get clear idea and to clarify doubts in spring.
    oneplus service center chennai
    oneplus service center in chennai
    oneplus service centre chennai
    oneplus service centre

    ReplyDelete
  3. Thanks for this blog. provided great information. All the details are explained clearly with the great explanation. Thanks for this wonderful blog. Step by step processes execution are given clearly.Know the details about different thing.
    password protect pdf file

    ReplyDelete
  4. Shooting Casino: Exclusive 150 Free Spins for €/$100
    Welcome to 제왕카지노 Shooting Casino! Our new players get a €/$100 no link 12bet deposit bonus and vua nhà cái a 150 free spins with bonus games. Get instant access to over 1,100 unique

    ReplyDelete