Web App publishing

Let’s create new Java web application. Startup Eclipse. File>New>Dynamic Web Project. Enter Project name: georeports-web.  Leave all defaults and add New Runtime.  Select Apache Tomcat v.6.0. Enter Tomcat installation directory: /home/DigMap/tomcat6 Download binary and finish with server wizard. Select newly created server and change defaults ports from 80XX to 70XX. (We alredy have one Tomcat instance running on port 8080, we’ll use this one for debug/testing). Again, we need to add Maven support and JasperReport dependency. Make a right click over project, Configure>Convert to Maven Project.  Leave defaults. Finish. Add dependency. This time beside jasperreport we’ll use GeoTool to query WFS data source. pom.xml file dependency is given below:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>georeports-web</groupId>
        <artifactId>georeports-web</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
        <build>
                <sourceDirectory>src</sourceDirectory>
                <plugins>
                        <plugin>
                                <artifactId>maven-compiler-plugin</artifactId>
                                <version>3.1</version>
                                <configuration>
                                        <source>1.7</source>
                                        <target>1.7</target>
                                </configuration>
                        </plugin>
                        <plugin>
                                <artifactId>maven-war-plugin</artifactId>
                                <version>2.4</version>
                                <configuration>
                                        <warSourceDirectory>WebContent</warSourceDirectory>
                                        <failOnMissingWebXml>false</failOnMissingWebXml>
                                </configuration>
                        </plugin>
                </plugins>
        </build>
        <dependencies>
                <dependency>
                        <groupId>org.geotools</groupId>
                        <artifactId>gt-wfs</artifactId>
                        <version>12-SNAPSHOT</version>
                </dependency>
                <dependency>
                        <groupId>org.geotools</groupId>
                        <artifactId>gt-cql</artifactId>
                        <version>12-SNAPSHOT</version>
                </dependency>
                <dependency>
                        <groupId>org.geotools</groupId>
                        <artifactId>gt-wms</artifactId>
                        <version>12-SNAPSHOT</version>
                </dependency>

                <dependency>
                        <groupId>net.sf.jasperreports</groupId>
                        <artifactId>jasperreports</artifactId>
                        <version>5.6.0</version>
                </dependency>
        </dependencies>

        <repositories>
                <repository>
                        <id>maven2-repository.dev.java.net</id>
                        <name>Java.net repository</name>
                        <url>http://download.java.net/maven/2</url>
                </repository>
                <repository>
                        <id>osgeo</id>
                        <name>Open Source Geospatial Foundation Repository</name>
                        <url>http://download.osgeo.org/webdav/geotools/</url>
                </repository>
                <repository> <!--Add the snapshot repository here -->
                        <snapshots>
                                <enabled>true</enabled>
                        </snapshots>
                        <id>opengeo</id>
                        <name>OpenGeo Maven Repository</name>
                        <url>http://repo.opengeo.org</url>
                </repository>
        </repositories>

</project>

Create res folder under WEB-INF. Move files CatalogOfEurope.jrxml and CatalogOfEurope.jasper into WEB-INF/res folder. Now we are ready for some coding. Create HTML landing page, index.html.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="author" content="Krunoslav Hrnjak">
<title>GeoReports | Catalog of the Europe</title>
</head>
<body>
	<h2>GeoReport | Catalog of the Europe</h2>
	<form method="POST" action="GeoReportGenerator" target="_blank"
		accept-charset="UTF-8">
		<input type="submit" value="Create a Catalog of the Europe" />
	</form>
	<br />
	<br />
	<br />
	<h3>
		<a href="http://www.yottabyte.hr" target="_blank">yottabyte</a>
	</h3>
</body>
</html>

We have to create some backend service that accepts our request and generate report. First we have to create a new Class to execute WFS query and convert it to JasperReports data source. Name it DataSourceUtility and place it in package hr.yottabyte.georeports.

public class DataSourceUtility {

    public static JRMapCollectionDataSource getDataSource (String geoServerAddr,
                        String layerName, String cqlFilter) throws Exception{
        String getCapabilities = geoServerAddr+"/ows?service=wfs&version=1.0.0&request=GetCapabilities";
        // Step 1 - connection parameters
        Map connectionParameters = new HashMap();
        connectionParameters.put("WFSDataStoreFactory:GET_CAPABILITIES_URL", getCapabilities );
        // Step 2 - connection
        DataStore data = DataStoreFinder.getDataStore( connectionParameters );
        // Step 4 - target
        SimpleFeatureSource source = data.getFeatureSource( layerName );
        Filter filter = CQL.toFilter(cqlFilter);
        Query query = new Query( layerName, filter );
        SimpleFeatureIterator iterator = source.getFeatures(query).features();
        List<Map<String,?>> maps = new ArrayList<Map<String, ?>> ();

        while (iterator.hasNext())
        {
            SimpleFeature feature = (SimpleFeature) iterator.next();
            BoundingBox bb = feature.getBounds();

            Map<String,Object> map = new HashMap<String, Object>();
            String countryName=feature.getAttribute("name_long").toString();
            map.put("opengeo:name_long",countryName);
            map.put("opengeo:postal",feature.getAttribute("postal").toString());
            map.put("opengeo:pop_est",feature.getAttribute("pop_est").toString());
            map.put("opengeo:continent",feature.getAttribute("continent").toString());
            map.put("gml:lowerCorner",bb.getMinY()+" "+bb.getMinX());
            map.put("gml:upperCorner",bb.getMaxY()+" "+bb.getMaxX());
            maps.add(map);
        }
        return  new JRMapCollectionDataSource(maps);
        }
}

And finally we have to create a Servlet class for POST request processing. Name it GeoReportGenerator and place it in package hr.yottabyte.georeports. Let’s do Servlet coding.  File>New>Servlet. Enter Java package: hr.yottybyte.georeports, and Class nameGeoReportGeneratorNextNext. Finish. We shall use pretty much the same code as in cmd line application. Main difference is in the way we find .jasper file, since we do not operate on file system anymore. Beside, CatalogOfEurope.jasper expect additional parameter gsURL – URL for delivery of WMS images.

package hr.yottabyte.georeports;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import net.sf.jasperreports.engine.DefaultJasperReportsContext;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JRPropertiesUtil;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;
import net.sf.jasperreports.engine.data.JRXmlDataSource;
import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRProperties;

/**
 * Servlet implementation class GeoReportGenerator
 */
public class GeoReportGenerator extends HttpServlet {
        private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public GeoReportGenerator() {
        super();
        // TODO Auto-generated constructor stub
    }

        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                // TODO Auto-generated method stub
        }

        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                        response.setContentType("text/html;charset=UTF-8");
                        response.setCharacterEncoding("UTF-8");
                        request.setCharacterEncoding("UTF-8");
                        byte[] pdfBytes = null;
                        try {

                                ServletContext context = getServletContext();
                                //get compiled report reference
                                InputStream jrIS = context.getResourceAsStream("/WEB-INF/res/CatalogOfEurope.jasper");
                                //load report
                                JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jrIS);
                                //set GeoServer URL
                                String gsURLString = "http://localhost:8080/geoserver";
                                //create hashmap for setting report params
                                Map<String, Object> params = new HashMap<String, Object>();
                                params.put("gsURL",gsURLString);
                                JRMapCollectionDataSource ds = DataSourceUtility.getDataSource(gsURLString,"opengeo:countries", "continent='Europe'");
                                pdfBytes = JasperRunManager.runReportToPdf(jasperReport,params, ds);
                        } catch (JRException e) {
                                htmlOutput(response,"<span class=\"bold\">Error occured!</span>");
                                e.printStackTrace();
                                return;
                        } catch (Exception e) {
                                // TODO Auto-generated catch block
                                htmlOutput(response,"<span class=\"bold\">Error occured!</span>");
                                e.printStackTrace();
                        }

                        if (pdfBytes != null) {
                                //return report as a pdf file
                                String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                                ServletOutputStream servletOutputStream = response.getOutputStream();
                                response.setContentType("application/pdf");
                                response.setContentLength(pdfBytes.length);
                                response.setHeader("Content-Disposition", "attachment" + "; filename="+date+"-DigMap-GeoReport.pdf");
                                servletOutputStream.write(pdfBytes, 0, pdfBytes.length);
                                servletOutputStream.flush();
                                servletOutputStream.close();
                                return;
                        } else {
                                htmlOutput(response,"<span class=\"bold\">Empty response.</span>");
                        }

                }

                public void htmlOutput( HttpServletResponse response, String htmlMessage) throws IOException{
                        response.setContentType("text/html");
                        PrintWriter outFail = response.getWriter();
                        outFail.println("<html>");
                        outFail.println("<head>");
                        outFail.println("<title>DigMap GeoReport Notification</title>");
                        outFail.println("</head>");
                        outFail.println("<body bgcolor=\"white\">");
                        outFail.println("<h1>DigMap GeoReport Notification</h1>");
                        outFail.println(htmlMessage);
                        outFail.println("</body>");
                        outFail.println("</html>");
                        outFail.close();

                }

So, now we have a one button application. After pressing the button, Catalog of Europe will start downloading to our computer.

Download whole eclipse project in .zip  georeports-web.zip

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s