CS636 Notes for class 16

Pizza2 Service Methods

makeOrder:  receives detached POJOs as arguments, has to check them out, since a Topping may no longer be available, etc.

(this could have happened in pizza1, actually)

Scenario causing bad Topping object in makeOrder call:

In makeOrder, the incoming PizzaSize and Toppings are specified by strings, but the corresponding MenuSize and MenuToppings may not exist.

To detect this defective order case, the pizza2 code looks up Pepperoni and finds out it isn’t really there, creates an Exception with a user message inside.

Note that this is a case of a ServiceException created by app logic, not a database problem.

If the topping were there, it would use it to create a new PizzaTopping.  Similarly with the PizzaSize object. Then a new PizzaOrder object. So the object graph sent to the DAO consists of only new objects. The DAO has to persist all these objects.

Alternatively, we could set up CASCADE for the relationships in PizzaOrder.java, like Murach has done for Invoice.java in the slides and on pg. 433. Then we could persist just the invoice object and the others would be persisted automatically.

Object Updates driving database updates

As an example, look at receiveOrders, which changes the status of one or more PizzaOrders. Although this code updates the pizza order, it doesn’t call a DAO method to do it.  The change to the PizzaOrder object is tracked by JPA’s persistence context, and the needed row update is made by commit time. 

Another note later in this code: eclipselink will read from presentation layer, outside the transaction. Maybe more configuration could prevent this lack of serializability.

Notes:

Question: what happens if you persist employee 158 and that PK is already in the DB?

Answer: An exception is thrown either immediately or later at commit time (or whenever the db is synch’d with the persistence context).  Commits can fail in any database programming environment. A successful transaction is one whose commit returns successfully.

Next: servlets, JSP hosted by tomcat.  You will install your own tomcat server on topcat first—in coming homework. Then you will be able to check for your assigned ports listed in a document linked to the class web page, as well as tomcat-8.5.zip and instructions.

Handout: Servlet1 Project

Servlets 

Servlet = Java Program running in a web server, doing App work

Readings on Servlets: read Servlet tutorial on web first (simpler), then tackle Murach Chap. 5

TOMCAT

Each student will be running a tomcat site.  Luckily, this is much easier than running a real production web server like Apache.

URL: http://topcat.cs.umb.edu:11600/cs636/index.html                                             

                                        local path, or sometimes “URI” : specifies which resource on the server should be accessed

In case of an .html file, the server just concatenates the local path onto the root path of the server’s website:

Ex: /home/eoneil/tomcat-8.0/webapps  + /cs636/index.html =

     /home/eoneil/tomcat-8.0/webapps/cs636/index.html = file to read and echo on TCP connection.

  Note: will be upgraded to tomcat-8.5 soon

In case of a servlet, say URL = http://topcat.cs.umb.edu:11600/cs636/hello

1.      TOMCAT interprets local path of an incoming GET/POST, determines webapp, usually just the first token of the local path, i.e. “cs636” here.

2.      TOMCAT looks in webapps/cs636 area for the web app’s web.xml file, finds mapping from “hello” to the .class file location

3.      TOMCAT instantiates the JAVA class of the servlet and calls its “doGet” or “doPost” method (After setting up request and response objects)

4.      Code in “doGet” or doPost is code for our web app, and can get user input from request parameters, create dynamic output

Ex. From Servlet Tutorial: now available as project servlet1 (linked under Resources>JEE)

HelloWorld.java
        
       import…
        
       public class HelloWorld extends HTTPServlet {
        
           public void doGet(HttpServletRequest request, // Carries in the user input from a form
                           HttpServeletResponse response) throws….
        
              Printwriter out = response.getWriter();        
              out.println(“Hello World!”);    // Dynmic html (Response back to browser)     
           } 
      }

To make this work:

-          Compile to .class file

-          Put file in right place on server, in tomcat’s webapps directory, webapps/servlet1/WEB-INF/classes/...

-          Provide a web.xml in servlet1/WEB-INF

-          access its URL

then a browser can access URL

Display “Hello World!”

How does execution reach a servlet?

For tomcat: A webapp (say myapp) has its files in tomcat’s webapps/myapp area. We put the servlet’s .class file in webapps/myapp/WEB-INF/classes/ area, specifically here classes/hall/HelloWorld.class. The structure for a certain webapp is standardized, so you can move a webapp from one app server to another.

Each web app with servlets has a file web.xml in its WEB-INF directory.  See Murach, pg. 47.  Tomcat (or other app server) hides the files in this directory from direct access by web service, i.e. a GET to  http://topcat.cs.umb.edu:11600/myapp/WEB-INF/anything  will fail.

Inside web.xml, there are <servlet> and <servlet-mapping> elements to guide tomcat to the .class file

Servlet1 project (zip) Similar servlet to tutoral: servlet1, prints date too

URL: http://topcat.cs.umb.edu:11600/servlet1/servlet/HelloWorld

With tunnel: http://localhost:11600/servlet1/servlet/HelloWorld

Source package cs636.hello.servlet, class HelloWorld

So .class file at /home/eoneil/cs636/tomcat-6.0/webapps/servlet1/WEB-INF/classes/cs636/hello/servlet/HelloWorld.class

Analysis of URL http://topcat.cs.umb.edu:11600/servlet1/servlet/HelloWorld 

servlet1’s build.xml has targets “build” to compile, “deploy” to copy to tomcat’s webapps

Also “test1” to use wget to send in a GET request to its URL, http://localhost:8080/servlet1/servlet/HelloWorld (on home PC)

How does ant know where the tomcat webapps directory is?

Need CATALINA_HOME env var

CATALINA_HOME=c:\tomcat-8.0        for ex. on home PC

CATALINA_HOME=/home/eoneil/cs636/tomcat-8.0     for ex. on Linux

How does ant know how to compose the right URL?

Need TOMCAT_URL env var:

TOMCAT_URL=http://localhost:8080    for ex. on home PC

TOMCAT_URL=http://topcat.cs.umb.edu:11600   for ex for Linux tomcat

So URL = ${TOMCAT_URL}/servlet1/servlet/HelloWorld

How is this particular URL specified for the servlet?

That’s done in web.xml, discussed in detail in Murach, pp 150-151

Email List Servlet Example in Chapter 2 and 5

ch05email project (zip) Slides (6pp)

Note that the email list examples in Chapter2 and Chapter 5 are identical in Java code, and almost identical otherwise.

So start by reading Chapter 2 and then continue in Chap. 5.  Look at the slides linked above.

Parts of ch05email (AKA ch02email) project:

URL for servlet here shown on pg. 135: Port 8080 is what we'll use for tomcat on home systems

localhost:8080/ch05email/emailList?action=add&firstName=John&lastName=Smith

Since the parameters show in the URL, we know this form uses method=get, not method= post. However, the online project has this page with method=post, as shown on pg. 37.

 <input type=”text” name=”firstName”>, etc. Also need hidden input “action” value=”add”

On submission of the form, the user input to these text boxes will be carried back to the server in name-value pairs, in the POST body (if the form has method="post") or in the GET's query string for method="get", shown in the URL above.

This page with the form was obtained with the URL "http://localhost/ch05email/", so it’s index.html/index.jsp in webapp “ch05email”, located in tomcat’s filesystem as webapps/ch05email/index.jsp

Pg. 135: see submission of form, showing URL generated by the form’s action= “emailList”.  This submission URL is a relative URL based on ch05email, so the URL generated by the browser is the above.

We need to understand how query string is processed, so the servlet code can get user input items. 

When tomcat receives this request, it parses the parameters and attaches them to the request object provided to the servlet in the doGet call.

In the servlet, we can pick up the parameter value from the request object by

   String firstName = request.getParameter(“firstName”);  // makes firstName = “John” in this case

See pg. 139.

This project is available at $cs636/ch05email, with a directory system compatible with eclipse web projects and a build.xml derived from the one for project servlet1.

We looked at the part of web.xml that determines the servlet class location and the url-pattern:   

   <servlet>
        <servlet-name>EmailListServlet</servlet-name>
        <servlet-class>murach.email.EmailListServlet</servlet-class>

   </servlet>
   <servlet-mapping>
        <servlet-name>EmailListServlet</servlet-name>
        <url-pattern>/emailList</url-pattern>
   </servlet-mapping>

The url-pattern specifies the part of the path after the webapp name, so /emailList means a full URL of http://server:host/ch05email/emailList. In Java webapps, unlike PHP webapps, you never need to know the webapp name for its code. You can rename the top-level directory in webapps and simply change the webapp name, with no need to change the code.

We could draw a page flow diagram with the form index.jsp (code, pg. 37) in the top box and thanks.jsp (code on pg. 47), the success report, in the lower box. There’s an arrow from the form to a big dot for the servlet, then on to thanks.jsp. That’s the success flow, which we’re now considering. In fact, the servlet can send the user back to the form if it finds null input.

The submit button of the form, when clicked, causes execution of the servlet because its action=”emailList” is a relative URL to the current directory, the one containing index.jsp, the root directory of the webapp located at webapps/ch05email in tomcat.  Thus when the browser does the GET, it is to the full URL of the servlet, along with parameters  http://localhost:8080/ch05email/emailList?action=add&firstName=John&lastName=Smith&email=jsmith@gmail.com

How does the servlet access the incoming parameters?

How does the servlet pass on this information to thanks.jsp (or its servlet)?

How does thanks.jsp get the information out into its response HTML so the user can see it?

The answer is “using EL”, the JSP expression language, which is covered in Chap. 6 (intro) and Chap. 8.

We see ${user.firstName} in thanks.jsp, and this compiles to user.getFirstName() in its servlet, where user has been retrieved from the request attribute by User user = request.getAttribute(“user”);