Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Finally! A Web App (Part 1)

DZone's Guide to

Finally! A Web App (Part 1)

We're finally moving towards a web app in the 3rd round of our web service shape calculator.

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

Introduction

If you have been with us from the start of this article series, we have been pretending to migrate some code into something more.  

A Make-Believe Storyline: You wrote something useful for yourself in Java a year ago because you had a regular need. (In our case, we are working with something I call a Shape Calculator).  You very quickly realized you should make it easier for yourself to use, and so established the boundaries of this code, put some thought and analysis to turning it into a reusable component.  It exists as an Eclipse Java (Maven) project.

You also developed a simple, menu-driven command-line app that utilizes this Shape Calculator. This app exists as a separate, independent Eclipse project.

After showing it to some of your cohorts in your department, they also liked it, but they suggested you needed to add persistence to it, and also that the command-line app needed to better expose the available functionality of this calculator service.

From the start, you chose to follow a Test-Driven Development approach, and relied on JUnit to drive your code enhancements and modifications.

So, a year has passed.  Several people in your department are using this calculator app and its underlying service or component, if you will.

Very recently, another department has caught wind of this application, and they are interested. They want you to web-enable this application.  Nothing fancy, just make the features available via a webpage.

Pick up where we last left off, here!

This article begins at this point: Exposing the Shape Calculator via a Web application.

Design, Look, and Feel

There are, of course, many ways we could go about this. I'm thinking quick and dirty, get it done.

Let's go with horizontal tabs for this web app.  It doesn't have to be really cool — just simple, easy to understand, and usable.

If, later on, this web app becomes popular (we are pretending, remember), then the front-end can be spoofed up and made to look professional, exciting, or whatever.

Here's and idea of what we would like our app to look like when we have it working:

Image title

Image title

We may add more tabs if we wish to more fully expose all of the Shape Calculator operations.

Setup Internal Managed Server

If you don't have one set up already, we will need a Tomcat server running within Eclipse.

I had previously downloaded Tomcat 8.5.4 (that being the latest release; I didn't want to deal with v9), and I placed it at: C:\apache-tomcat-8.5.4 

There are plenty of articles on installing Tomcat, but if you are running Eclipse Neon (or earlier), this particular install is not so straightforward. And the reason is that when Eclipse asks for what version...

Image title

... you'll want to pick "Apache Tomcat v8.0", except it will not work.

(If you aren't having this issue, move on, soldier)

Let's use Cygwin for what we need to do.  Open a new Cygwin terminal.  Change directory ("cd") to where you've placed the Tomcat 8.5.4 folder. Remember that you can type a letter and then tab to auto-complete your way to your destination (I did exactly that in the image below).

Our goal is to extract one file out of the catalina.jar, make a modification, and put the updated file back in the jar.

Let's pretend we don't know where the jar is located.  So we will "find" the jar.

Image title

Once you have located the jar (in the "lib" directory), change the directory to that location, create a temp directory, and make a copy of the catalina.jar into the temporary directory (see above). Then move into the temp directory yourself.

I then did a search within the jar for any filenames with "erver" (Server, server).

All of them were Java classes, except one: ServerInfo.properties

Image title

We need to extract that file and modify its contents.

Image title

Take a look at the file contents by "cat"ting it:  $ cat org/apache/catalina/util/ServerInfo.properties 

You will need to edit that file so it looks like so:

Image title

Now we need to put that file back in the jar, and copy the modified catalina.jar up one diretory to "lib".

Image title

Ok, so, you now should be able to add this Tomcat as a server in Eclipse, choose "version 8", and finish your server setup.

Create a New Web Project

Let's create a new Dynamic Web Project in Eclipse.

Following along in the project-creation wizard, I chose the project name as "webapp-dep-on-shape-calc-jpa-hibernate" and made sure to have it use our internal Tomcat server.

Image title

I removed the original src folder and added some standard Maven folders, just as in the first article of the series.

Let's Work Top-Down If Possible

Image title

One of our goals is to use Pure Java Config, but let's begin with web.xml for now. I then converted my new project to a Maven project.

Let's create a "pages" folder under the WEB-INF folder of the project and create a simple "index.jsp" page.

Image title

Name it "index.jsp", click "Next", select "New JSP File (html)", and click "Finish".

Open the "web.xml" file that the project-creation wizard placed in the WEB-INF folder, and remove the entire "<welcome-file-list>......</welcome-file-list>" block.

We will be using Spring MVC, so let's add our dispatcher servlet to the web.xml:

  <servlet>
  <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>
             org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
      <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
  </servlet-mapping>

Then I started the server, and I saw this:

INFO: Starting service Catalina

Sep 07, 2016 11:26:19 AM org.apache.catalina.core.StandardEngine startInternal

INFO: Starting Servlet Engine: Apache Tomcat/8.0.0

Sep 07, 2016 11:26:21 AM org.apache.catalina.core.ApplicationContext log

INFO: Marking servlet mvc-dispatcher as unavailable

Sep 07, 2016 11:26:21 AM org.apache.catalina.core.StandardContext loadOnStartup

SEVERE: Servlet [mvc-dispatcher] in web application [/webapp-p1] threw load() exception

java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1284)

Looks like we forgot something: A Maven dependency:

<properties>

<maven.compiler.target>1.8</maven.compiler.target>

<maven.compiler.source>1.8</maven.compiler.source>

<spring.version>4.3.2.RELEASE</spring.version>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>



<dependencies>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>${spring.version}</version>

</dependency>

After a Maven update and re-build, re-deploy of project, I started Tomcat again:

Sep 07, 2016 11:38:29 AM org.apache.catalina.core.StandardContext loadOnStartup

SEVERE: Servlet [mvc-dispatcher] in web application [/webapp-p1] threw load() exception

java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]

So let's create that file where it is expected.  Here are the minimal file content s :

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
    ">

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

</beans>

We re-build, re-deploy, re-start... and this time we have a clean start of the server.

However, we're not going to see anything good if we point a browser to the base URL.

I right-click on the project then -> Properties, then select "Web Project Settings" and get my context-root path.

Since I am writing these articles, I use different projects along the way; thus this particular URL will not match our stated project. It should be http://localhost:8080/webapp-dep-on-shape-calc-jpa-hibernate/, but for me at the moment it is http://localhost:8080/webapp-p1/ (because my code has to match the articles).

In any case, we both will see a 404 return code.

We are missing a Controller in mvc-dispatcher-servlet.xml. I add one:

    <bean name="/"
        class="com.eli.calc.shape.mvc.controllers.RequestResponseController" />

That means we need to create that class:

Image title

Build-Deploy-Start, now we're getting somewhere. Our browser now shows:

Image title

Let's add a simple handler method to our Controller:

package com.eli.calc.shape.mvc.controllers;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

public class RequestResponseController {

    @RequestMapping(value="/",method=RequestMethod.GET)
    public ModelAndView welcome() {

        System.err.println("\n\n\nWelcome\n\n\n");

        return new ModelAndView("index","message","Hi");

    }
}

The @RequestMapping(....) annotation, maps the URL to that method in the Controller.

That is, if you enter "http://localhost:8080/webapp-dep-on-shape-calc-jpa-hibernate/" , you should see the "Welcome" in the console output, and the index.jsp page should display, with a message in the body:  "Hi"

The above mapping allows for some dynamic content generation and display back at the JSP.

More on this later.

Build-Deploy-Start, and we get a clean page. The Tomcat start-up console output shows:

Image title

Another note:

Had you used

        class="org.springframework.web.servlet.view.UrlBasedViewResolver"

instead of

        class="org.springframework.web.servlet.view.InternalResourceViewResolver"

You probably would have seen startup errors.

InternalResourceViewResolver  is a sub-class of UrlBasedViewResolver

Next Steps

I think we are about ready to begin laying out and trying our UI.  But right before we do that, let's convert from XML-based configuration to Java-based.

To be continued in the next article!

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:
java 8 ,j2ee ,jsp ,bootstrap ,javascript ,spring mvc ,cygwin

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}