목요일, 3월 28
Shadow

#031 Servlet 3.0

Java Servlet 3.0 (JSR 315), which is part of Java EE 6, is a major revision of the Java Servlet technology, a widely accepted technology for building dynamic content for web-based applications, and includes changes to enable easy pluggability of popular open-source frameworks or libraries, ease of development leveraging annotation and making web.xml optional, support for async processing, which enables writing Comet applications in portable fashion, security enhancements, and other minor updates to the existing APIs.

In this lab, you are going exercise all the newly introduced features of Servlet 3.0.

Expected duration: 210 minutes (excluding homework)

 

 

Software Needed

Before you begin, you need to install JDK 6 and NetBeans IDE 6.8.  You also need to download and unzip the hands-on lab zip file below.

  • 4532_javaee6_servlet3.0.zip (download)
    • It contains this document and the lab contents
    • Download it and unzip in a directory of your choice

 

OS platforms you can use

  • Windows
  • Solaris x86, Solaris Sparc
  • Linux
  • Mac OS X

Lab Exercises

For the sake of the simplicity of the lab, most exercises are provided in the form of “ready-to-open-and-run” NetBeans projects.  (Many of them are borrowed from “glassfish-samples” and “Java EE 6 tutorial“.)  Please feel free to create them from scratch if you want to.

It is strongly encouraged, leveraging what is provided in this lab, you do your own experimentation meaning creating/adding your own code as much as you can.

If you have written some code that might help everyone else, please feel free to share them on this codecamp email alias or directly send them to the instructors.  Your name will be recognized in this lab if your sample code is chosen to be included.  For the tasks that need to be done, please see the “Things to be done” section above.)

Exercise 1: Annotation

In this exercise, you are going to learn how to use annotations to define a Servlet, Filter, thus eliminating the need of the web.xml.

  1. Open, build, and run “annotation-war” sample application
  2. Study the code
  3. Add your own Servlet

 

 

(1.1) Open, build, and run “annotation-war” sample application (from “glassfish-samples”)

0. Start NetBeans IDE.
1. Open annotation-war NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).


Figure-1.11

  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/web/servlet directory.
  • Select annotation-war.
  • Click Open Project.


Figure-1.12

  • Observe that the annotation-war project node appears under Projects tab window.

2. Build and run annotation-war project.

  • Right-click annotation-war project and select Run.


Figure-1.13

  • Observe that the default browser gets displayed with a result.


Figure-1.14

(1.2) Study the source code

1. Study TestServlet.java.

  • The @WebServlet annotation is used to define a Servlet.
  • The only mandatory attribute is urlPatterns attribute.


Figure-1.21

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only (“GPL”) or the Common Development
* and Distribution License(“CDDL”) (collectively, the “License”).  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the “Classpath” exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: “Portions Copyrighted [year]
* [name of copyright owner]”
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding “[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license.”  If you don’t indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package web.servlet.annotation_war;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* This class illustrates WebServlet annotation.
*
* @author Shing Wai Chan
*/
@WebServlet(name=”mytest”,
urlPatterns={“/”},
initParams={ @WebInitParam(name=”message”, value=”my servlet”) } )
public class TestServlet extends HttpServlet {
private String listenerMessage = null;

@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
listenerMessage = (String)config.getServletContext().getAttribute(“listenerMessage”);
}

@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {

PrintWriter writer = res.getWriter();
writer.write(“Hello, ” + getInitParameter(“message”) + “, “);
writer.write(req.getAttribute(“filterMessage”) + “, “);
writer.write(listenerMessage + “.\n”);
}
}

TestServlet.java

2. Display and study the context sensitive Javadoc on @WebServlet annotation.  In NetBeans IDE, you can display the Javadoc of a class by right clicking it and selecting Show Javadoc.

  • Move the cursor to the @WebServlet(..), right click it, and select Show Javadoc.


Figure-1.22

  • Observe that the Javadoc of the @WebServlet annotation class gets displayed.


Figure-1.23

3. Study TestFilter.java.

package web.servlet.annotation_war;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

/**
* This class illustrates WebFilter annotation.
*
* @author Shing Wai Chan
*/
@WebFilter(urlPatterns={“/”}, initParams={ @WebInitParam(name=”mesg”, value=”my filter”) })
public class TestFilter implements Filter {
String mesg = null;

public void init(FilterConfig filterConfig) throws ServletException {
mesg = filterConfig.getInitParameter(“mesg”);
}

public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {

req.setAttribute(“filterMessage”, mesg);
chain.doFilter(req, res);
}

public void destroy() {
}
}

TestFilter.java

  • Study the @WebFilter annotation by moving the cursor to @WebFilter(..), right clicking it, and selecting Show Javadoc.

4. Study TestServletContextListener.java.

package web.servlet.annotation_war;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;

/**
* This class illustrates WebListener annotation.
*
* @author Shing Wai Chan
*/
@javax.servlet.annotation.WebListener
public class TestServletContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
context.setAttribute(“listenerMessage”, “my listener”);
}

public void contextDestroyed(ServletContextEvent sce) {
}
}

TestServletContext.java

  • Study the @WebListener annotation by moving the cursor to @…WebListener(..), right clicking it, and selecting Show Javadoc.

5. Observe that there is no web.xml file.

  • There is no need for web.xml since every configuration can be done through annotation.


Figure-1.24

(1.3) Add your own servlet

1. Create a new servlet.


Figure-1.31

  • For the Class Name field, enter MyOwnServlet.
  • Click Next.


Figure-1.32

  • Observe that you may register the servlet by checking the Add information to deployment descriptor (web.xml). Do not check it for this exercise.
  • Click Finish.


Figure-1.32b

2. Modify the IDE generated MyOwnServlet.java as shown below.  The code fragments that need to be added or modified are highlighted in bold and red-colored font.

  Tip: Note that you may use code completion via the Source->Complete code… menu or via the corresponding shortcut (which you may adapt in Preferences if it is already used system-wide).

package web.servlet.annotation_war;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
*
* @author sang
*/
@WebServlet(name=”MyOwnServlet”, urlPatterns={“/MyOwnServlet”},
initParams={ @WebInitParam(name=”mymessage”, value=”passion”) } )
public class MyOwnServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {
//
out.println(“<html>”);
out.println(“<head>”);
out.println(“<title>Servlet MyOwnServlet</title>”);
out.println(“</head>”);
out.println(“<body>”);
out.println(“<h1>My message is ” + getInitParameter(“mymessage”)  + “</h1>”);
out.println(“</body>”);
out.println(“</html>”);
//
} finally {
out.close();
}
}

// <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”>
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return “Short description”;
}// </editor-fold>

}

MyOwnServlet .java


Figure-1.33

3. Build and run.

  • Right click annotation-war project node and select Run.
  • Observe that the default browser gets displayed with a result.
  • Change the URL to http://localhost:8080/annotation-war/MyOwnServlet  – add /MyOwnServlet at the end – and click Return.
  • Observe that “My message is passion” message gets displayed.


Figure-1.34

 

 

Summary

In this exercise,  you have learned how to use @WebServlet for defining a servlet, and @WebFilter for defining a filter.

 

Exercise 2: Dynamic registration

Servlet 3.0 provides enhanced Pluggability where it provides options for adding servlets, filters, servlet mappings and filter mappings during run time.

In this exercise, you are going to learn how to dynamically add a servlet and filter (instead of statically configuring them at the compile time.)

  1. Open, build, and run “dynamicregistration-war” sample application (from “glassfish-samples”)
  2. Study the code
  3. Register your own servlet dynamically

 

(2.1) Open, build, and run “dynamicregistration-war” sample application (from “glassfish-samples”)

1. Open dynamicregistration-war NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/web/servlet directory.
  • Select dynamicregistration-war.
  • Click Open Project.

2. Build and run dynamicregistration-war project.

  • Right-click dynamicregistration-war project and select Run.
  • Observe that the default browser gets displayed with a result.


Figure-2.11

(2.2) Study the code

The blue-colored and bold fonted comments are not in the source code but are added in this document to help you understand the code better.

1. Study TestServlet.java.

package web.servlet.dynamicregistration_war;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/**
* Servlet that is registered by the
* <tt>web.servlet.dynamicregistration_war.TestServletContextListener</tt>.
*
* <p>This Servlet verifies that the initialization parameter that was
* added by the <tt>TestServletContextListener</tt> when it registered the
* Servlet is present in its <tt>ServetConfig</tt>.
*
* <p>The Servlet also verifies that the Filter mapped to it has been
* invoked, by checking the request for the presence of the Filter’s
* initialization parameter that was added by the
* <tt>TestServletContextListener</tt> when it registered the Filter,
* and was set on the request (as a request attribute) by the Filter as
* the request passed through the Filter.
*
* <p>If any of the verification steps fail, the Servlet will throw an
* Exception. Otherwise, it outputs the string <tt>HELLO WORLD!</tt> to the
* response.
*
* @author Jan Luehe
*/
public class TestServlet extends HttpServlet {

@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {

// Test if dynamic registration of a servlet with init parameters is
// done correctly.
if (!”servletInitValue”.equals(getServletConfig().getInitParameter(
“servletInitName”))) {
throw new ServletException(“Missing servlet init param”);
}

// Test if dynamic registration of a filter with init parameters is
// done correctly.
if (!”filterInitValue”.equals(req.getAttribute(“filterInitName”))) {
throw new ServletException(“Missing request attribute that was ” +
“supposed to have been set by programmtically registered ” +
“Filter”);
}

// Test if dynamic registration of a ServletRequestListener is
// done correctly.
if (!”listenerAttributeValue”.equals(req.getAttribute(
“listenerAttributeName”))) {
throw new ServletException(“Missing request attribute that was ” +
“supposed to have been set by programmtically registered ” +
“ServletRequestListener”);
}

res.getWriter().println(“HELLO WORLD!\n”);
}
}

TestServlet.java

2. Study  TestServletContextListener.java.

package web.servlet.dynamicregistration_war;

import java.util.*;
import javax.servlet.*;

/**
* ServletContextListener that registers a Servlet (with
* name <tt>DynamicServlet</tt>) and Filter (with name
* <tt>DynamicFilter</tt>) in response to the <tt>contextInitialized</tt>
* event.
*
* <p>The <tt>DynamicServlet</tt> is configured with an initialization
* parameter and mapped to a URL pattern equal to <tt>/*</tt>.
*
* <p>The <tt>DynamicFilter</tt> is also configured with an initialization
* parameter and mapped to the <tt>DynamicServlet</tt> such that it will
* intercept any requests mapped to the <tt>DynamicServlet</tt>.
*
* @author Jan Luehe
*/
public class TestServletContextListener implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent sce) {

ServletContext sc = sce.getServletContext();

// Register Servlet
ServletRegistration sr = sc.addServlet(“DynamicServlet”,
“web.servlet.dynamicregistration_war.TestServlet”);
sr.setInitParameter(“servletInitName”, “servletInitValue”);
sr.addMapping(“/*”);

// Register Filter
FilterRegistration fr = sc.addFilter(“DynamicFilter”,
“web.servlet.dynamicregistration_war.TestFilter”);
fr.setInitParameter(“filterInitName”, “filterInitValue”);
fr.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),
true, “DynamicServlet”);

// Register ServletRequestListener
sc.addListener(“web.servlet.dynamicregistration_war.TestServletRequestListener”);
}

@Override
public void contextDestroyed(ServletContextEvent sce) {
// Do nothing
}
}

TestServletContextListener.java

3. TestServletRequestListener.java

package web.servlet.dynamicregistration_war;

import javax.servlet.*;

public class TestServletRequestListener implements ServletRequestListener {

/**
* Receives notification that a request is about to enter the scope
* of the web application.
*
* @param sre The ServletRequestEvent
*/
public void requestInitialized(ServletRequestEvent sre) {
// Add listenerAttributeName attribute to the request scope
sre.getServletRequest().setAttribute(“listenerAttributeName”,
“listenerAttributeValue”);
}

/**
* Receives notification that a request is about to leave the scope
* of the web application.
*
* @param sre The ServletRequestEvent
*/
public void requestDestroyed(ServletRequestEvent sre) {
// Do nothing
}

}

TestServletRequestListener.java

(2.3) Register your own servlet dynamically

1. Add MyOwnServlet2.java to the project.
2. Modify the IDE generated MyOwnServlet2.java as shown below.  The code fragments that need to added/modified are highlighted in bold and red-colored font.

package web.servlet.dynamicregistration_war;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
*
* @author sang
*/
// Removed @WebSerlvet annotation since we are registering
// this servlet dynamically.
public class MyOwnServlet2 extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {
//
out.println(“<html>”);
out.println(“<head>”);
out.println(“<title>Servlet MyOwnServlet2</title>”);
out.println(“</head>”);
out.println(“<body>”);
out.println(“<h1>My message2 is ” + getInitParameter(“mymessage2”)  + “</h1>”);
out.println(“</body>”);
out.println(“</html>”);
//
} finally {
out.close();
}
}

// <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”>
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return “Short description”;
}// </editor-fold>

}

MyOwnServlet2.java


Figure-2.31

2. Modify the TestServletContextListener.java as shown below.

package web.servlet.dynamicregistration_war;

import java.util.*;
import javax.servlet.*;

/**
* ServletContextListener that registers a Servlet (with
* name <tt>DynamicServlet</tt>) and Filter (with name
* <tt>DynamicFilter</tt>) in response to the <tt>contextInitialized</tt>
* event.
*
* <p>The <tt>DynamicServlet</tt> is configured with an initialization
* parameter and mapped to a URL pattern equal to <tt>/*</tt>.
*
* <p>The <tt>DynamicFilter</tt> is also configured with an initialization
* parameter and mapped to the <tt>DynamicServlet</tt> such that it will
* intercept any requests mapped to the <tt>DynamicServlet</tt>.
*
* @author Jan Luehe
*/
public class TestServletContextListener implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent sce) {

ServletContext sc = sce.getServletContext();

// Register Servlet
ServletRegistration sr = sc.addServlet(“DynamicServlet”,
“web.servlet.dynamicregistration_war.TestServlet”);
sr.setInitParameter(“servletInitName”, “servletInitValue”);
sr.addMapping(“/*”);

// Register my own Servlet
sr = sc.addServlet(“DynamicServlet2”,
“web.servlet.dynamicregistration_war.MyOwnServlet2”);
sr.setInitParameter(“mymessage2”, “Passion2”);
sr.addMapping(“/myown/*”);

// Register Filter
FilterRegistration fr = sc.addFilter(“DynamicFilter”,
“web.servlet.dynamicregistration_war.TestFilter”);
fr.setInitParameter(“filterInitName”, “filterInitValue”);
fr.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),
true, “DynamicServlet”);

// Register ServletRequestListener
sc.addListener(“web.servlet.dynamicregistration_war.TestServletRequestListener”);
}

@Override
public void contextDestroyed(ServletContextEvent sce) {
// Do nothing
}
}

TestServletContextListener.java


Figure-2.32

3. Modify TestServlet.java.

package web.servlet.dynamicregistration_war;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/**
* Servlet that is registered by the
* <tt>web.servlet.dynamicregistration_war.TestServletContextListener</tt>.
*
* <p>This Servlet verifies that the initialization parameter that was
* added by the <tt>TestServletContextListener</tt> when it registered the
* Servlet is present in its <tt>ServetConfig</tt>.
*
* <p>The Servlet also verifies that the Filter mapped to it has been
* invoked, by checking the request for the presence of the Filter’s
* initialization parameter that was added by the
* <tt>TestServletContextListener</tt> when it registered the Filter,
* and was set on the request (as a request attribute) by the Filter as
* the request passed through the Filter.
*
* <p>If any of the verification steps fail, the Servlet will throw an
* Exception. Otherwise, it outputs the string <tt>HELLO WORLD!</tt> to the
* response.
*
* @author Jan Luehe
*/
public class TestServlet extends HttpServlet {

@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {

if (!”servletInitValue”.equals(getServletConfig().getInitParameter(
“servletInitName”))) {
throw new ServletException(“Missing servlet init param”);
}

String initName = getServletConfig().getInitParameter(“mymessage2”);
res.getWriter().println(“mymessage2 = ” + initName);

if (!”filterInitValue”.equals(req.getAttribute(“filterInitName”))) {
throw new ServletException(“Missing request attribute that was ” +
“supposed to have been set by programmtically registered ” +
“Filter”);
}

if (!”listenerAttributeValue”.equals(req.getAttribute(
“listenerAttributeName”))) {
throw new ServletException(“Missing request attribute that was ” +
“supposed to have been set by programmtically registered ” +
“ServletRequestListener”);
}

res.getWriter().println(“HELLO WORLD!\n”);
}
}

Modified TestServlet.java


Figure-2.32b

4. Build and run.

  • Right click the project node and select Run.
  • Observe that the default browser gets displayed with a result.
  • Change the URL to http://localhost:8080/dynamicregistration-war/myown  – add /myown at the end – and click Return.
  • Observe that “My message2 is Passion2” message gets displayed.


Figure-2.33

Summary

In this exercise,  you have learned how to dynamically add a servlet and filter (instead of statically configuring them at the compile time.)

 

Exercise 3: Pluggability of 3rd-party frameworks/libraries

Under Servlet 3.0, a pluggable framework or library is bundled in the form of a jar file and it is the responsibility of that framework or library to define a web fragment file with the name web-fragment.xml in the META-INF directory of the jar file. During the application startup, it is the responsibility of the Container to scan the information that is found in the /META-INF/web-fragment.xml file available in the application’s classpath.

  1. Open, build, and run “absolute-ordering-web-fragments-war” sample application
  2. Study the code
  3. Add your own library

 

(3.1) Open, build, and run “absolute-ordering-web-fragments-war” sample application (from “glassfish-samples”)

1. Open absolute-ordering-web-fragments-war NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/web/servlet directory.
  • Select absolute-ordering-web-fragments-war.
  • Check Open Required Projects.
  • Click Open Project.


Figure-3.12a

  • Observe that the absolute-ordering-web-fragments-war project node appears under Projects tab window together with the required projects.

 


Figure-3.12

2. Build and run absolute-ordering-web-fragments-war project.

  • Right-click absolute-ordering-web-fragments-war project and select Run.
  • Observe that the default browser gets displayed with a result.


Figure-3.13

(3.2) Study the code

1. Study TestServlet.java.

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only (“GPL”) or the Common Development
* and Distribution License(“CDDL”) (collectively, the “License”).  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the “Classpath” exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: “Portions Copyrighted [year]
* [name of copyright owner]”
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding “[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license.”  If you don’t indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package web.servlet.absolute_ordering_web_fragments_war;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(“/”)
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {

// Display the value of filterMessage attribute saved in the request scope
String message = “filterMessage=” + req.getAttribute(“filterMessage”);
res.getWriter().println(message);
}
}

TestServlet.java

2. Study web.xml.  The absolute ordering of libraries are specified as a library whose name is A is loaded first, and the one whose name is B is loaded last while all the other libraries are loaded between A and B.


Figure-3.21

3. Observe that three libraries – webfragment1.jar, webfragment2.jar, webfragment3.jar – are configured into the application. They are configured under WEB_INF/lib directory.

  • Click Files tab.
  • Expand absolute-ordering-web-fragments-war->build->web->WEB-INF->lib.
  • Observe that webfragment2.jar and webfragment3.jar have web-fragment.xml files under META-INF directory while webfragment1.jar does not.


Figure-3.22

3. Study the web-fragment.xml of the webfragment2 library.


Figure-3.23


Figure-3.24

<web-fragment xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” version=”3.0″ xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd” metadata-complete=”true”>
<name>A</name>
<filter>
<icon/>
<filter-name>wf2testfilter</filter-name>
<filter-class>
web.servlet.absolute_ordering_web_fragments_war.webfragment2.Wf2TestFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>wf2testfilter</filter-name>
<url-pattern>/</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-fragment>

4. Study the Wf2TestFilter.java of the webfragment2 library.


Figure-3.24

package web.servlet.absolute_ordering_web_fragments_war.webfragment2;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

// The Wf2TestFilter is configured in the web-fragment.xml of the webfragment2 library.
public class Wf2TestFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}

public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {

// When doFilter method of this filter is called, add “2” to
// the filterMessage.
String filterMessage = (String)req.getAttribute(“filterMessage”);
if (filterMessage == null) {
filterMessage = “”;
}
filterMessage += “2”;

req.setAttribute(“filterMessage”, filterMessage);
chain.doFilter(req, res);
}

public void destroy() {
}
}

5. Study the web-fragment.xml of the webfragment3 library.


Figure-3.26

(3.3) Create a new library step by step

In this step, you are going to build your own Java library, which you will add to the absolute-ordering-web-fragment-war application as another pluggable 3rd-party library.

1. Create a new Java Library project.


Figure-3.31


Figure-3.32

  • For the Project Name field, enter my_webfragment (or whatever project name of your choice).
  • Click Finish.


Figure-3.33

2. Add a Java class to the project.


Figure-3.34

  • For the Class Name field, enter MyFilter (or whatever Class name of your choice).
  • For the Package field, enter mypackage (or whatever package name of your choice).
  • Click Finish.


Figure-3.35

  • Modify the IDE generated MyFilter.java with the code below.  This is the same code as webfragment3 library’s Wf3TestFilter.java except the filterMessage is set with ” Passion” as shown below.
package mypackage;

import java.io.IOException;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

@WebFilter(urlPatterns={ “/” }, dispatcherTypes= { DispatcherType.REQUEST })
public class MyFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}

public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {

String filterMessage = (String)req.getAttribute(“filterMessage”);
if (filterMessage == null) {
filterMessage = “”;
}
filterMessage += ” Passion”;

req.setAttribute(“filterMessage”, filterMessage);
chain.doFilter(req, res);
}

public void destroy() {
}
}

MyFilter.java

  • Observe that there are lots of compile errors.

3. Add Java-EE-GlassFish-v3 library to the my_webfragment project.


Figure-3.36


Figure-3.37

  • Observe that all the compile errors are resolved.

4. Add web-fragment.xml to the library.


Figure-3.38


Figure-3.39


Figure-3.40

  • Modify the IDE generated web-fragment.xml with the one below.  Note that the name of the library is set to Passion.
<?xml version=”1.0″ encoding=”UTF-8″?>

<web-fragment xmlns=”http://java.sun.com/xml/ns/javaee”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd”
version=”3.0″>
<name>Passion</name>
</web-fragment>

  Tip: Alternatively you may enter the name of the library in the Name(s) field of the General tab of the web-fragment.xml file.


Figure-3.40a

5. Build the library.


Figure-3.41

6. Add the Passion library to the absolute-ordering-web-fragments-war application.


Figure-3.42

  • Browse down to the directory where you created my_webfragment project – \myprojects in this example.


Figure-3.43

7.  Modify the web.xml of the absolute-ordering-web-fragments-war application.  The change is to load the Passion library right after A library.


Figure-3.44

  Warning: Do not use Ordering in the General part of web-fragment.xml file. It will remove silently the <others/> tag as it has no contents.

8. Run the application.


Figure-3.45

  • Observe that the filterMessage attrbute now contains ” Passion”.


Figure-3.46

Summary

In this exercise,  you have learned how to add a pluggable framework or library in the form of a jar file and how to define a web fragment file with the name web-fragment.xml in the META-INF directory of the jar file.

Exercise 4: Resources in bundled jar

In this exercise, you are going to build, run, study, and modify the “jsp-resource-in-bundled-jar-war” sample application, which demonstrates how dynamic and static resources bundled inside the META-INF/resources directory of a JAR file inside the application’s WEB-INF/lib directory may be accessed in the same way as if they had been placed in the application’s document root.

  1. Open, build, and run “jsp-resource-in-bundled-jar-war” sample application
  2. Study the code
  3. Create a new jar with your own resource

 

(4.1) Open, build, and run “jsp-resource-in-bundled-jar-war” sample application (from “glassfish-samples”)

1. Open jsp-resource-in-bundled-jar-war NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/web/servlet directory.
  • Select jsp-resource-in-bundled-jar-war.
  • Click Open Project.
  • Observe that the jsp-resource-in-bundled-jar-war project node appears under Projects tab window.

2. Build and run jsp-resource-in-bundled-jar-war project.

  • Right-click jsp-resource-in-bundled-jar-war project and select Run.
  • Observe that the default browser gets displayed with a result.


Figure-4.11

(4.2) Study the code

1. Observe that dynamicResources.jar contains META-INF->resources->jsp->helloWorld.jsp.


Figure-4.21

2. Observe that the Relative URL of the project is set to jsp/helloWorld.jsp.

  • Right click project and select Properties.
  • Select Run on the left and observe that the Relative URL field is set to jsp/helloWorld.jsp.


Figure-4.22

(4.3) Create a new jar file with our own resource

In this step, you are going to add your own resources – a  JSP file called helloKorea.jsp – into the my_webfragment library you created in previous exercise.  The resources should be under META-INF/resources directory of the my_webfragment library.
1. Copy the resources from dynamicResources to the my_webfragment library.  (For the sake of the simplicity of the exercise, we are copying and modifying the resources of the former into the latter – you can certainly create them from scratch.)

  • Right click resources under dynamicResources.jar->META-INF and select Copy.

Figure-4.31

  • Right click META-INF of the my_webfragment and select Paste.


Figure-4.32

2. Modify the helloWorld.jsp.


Figure-4.33

3. Rename the helloWorld.jsp.


Figure-4.34


Figure-3.35

4. Click Save all button, so that the library is recompiled.
5. Add the my_webfragment library to the jsp-resource-in-bundled-jar-war application.


Figure-4.36

  • Browse down to the directory where you created the my_webfragment library project.
  • Select the my_webfragment library project.
  • Click Add Project JAR Files button.


Figure-4.37

6. Change the Relative URL property of the jsp-resource-in-bundled-jar-war application.


Figure-4.38

  • Select Run on the left.
  • For the Relative URL field, enter jsp/helloKorea.jsp.
  • Click OK.


Figure-4.39

7. Build and run the the jsp-resource-in-bundled-jar-war application.

  • Right click project and select Run.
  • Observe that the default browser gets displayed with a result.


Figure-4.40

Summary

In this exercise,  you have learned how dynamic and static resources can be bundled inside the META-INF/resources directory of a JAR file inside the application’s WEB-INF/lib directory as if they had been placed in the application’s document root.

Exercise 5: Asynch. Servlet

One of the significant enhancements made in JSR 315: Java Servlet 3.0, is support for asynchronous processing. With this support, a servlet no longer has to wait for a response from a resource such as a database before its thread can continue processing, that is, the thread is not blocked.  Previous to Servlet 3.0, asynchronous support in the Java EE web container was provided in a proprietary way — either through APIs built on top of the Servlet 2.5 API or through non-Servlet APIs or implementations.

  1. Open, build, and run “servlet3.0_async_simple_dispatch” sample application
  2. Study the code
  3. Open, build, and run “servlet3.0_async_simple_complete” sample application
  4. Study the code
  5. Open, build, and run “servlet3.0_async_simple_listener_completed” sample application
  6. Study the code
  7. Open, build, and run “servlet3.0_async_simple_listener_timeout” sample application
  8. Study the code
  9. Open, build, and run “async-request-war” sample application
  10. Study the code

 

(5.1) Open, build, and run “servlet3.0_asynch_simple_dispatch” sample application (from “lab samples”)

1. Open servlet3.0_asynch_simple_dispatch NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/samples directory.
  • Select servlet3.0_asynch_simple_dispatch.
  • Click Open Project.
  • Observe that the servlet3.0_asynch_simple_dispatch project node appears under Projects tab window.

2. Build and run servlet3.0_asynch_simple_dispatch project.

  • Right-click servlet3.0_asynch_simple_dispatch project and select Run.
  • Observe that browser gets displayed.


Figure-5.11

  • Wait a couple of seconds and observe that a response page is displayed.


Figure-5.12

(5.2) Study the code

1. index.html

<html>
<head><title></title></head>
<body>
<h1>Call an Asynch Servlet</h1>

<form action=”AsynchServlet”>
<input type=”submit” value =”Click me”/>
</form>

</body>
</html>

index.html

2. response.jsp

<%@page contentType=”text/html” pageEncoding=”UTF-8″%>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
“http://www.w3.org/TR/html4/loose.dtd”>

<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title></title>
</head>
<body>
<h1>This page gets displayed after asynch. Servlet is called.</h1>
</body>
</html>

3. AsynchServlet.java

package asyncpackage;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.servlet.AsyncContext;

@WebServlet(urlPatterns = “/AsynchServlet”, asyncSupported = true)
public class AsynchServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

AsyncContext aCtx = request.startAsync(request, response);
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.execute(new AsynchRunnable(aCtx));

}
}

AsynchServlet.java

  • Display Javadoc of the AsyncContext class.


Figure-5.21


Figure-5.22

4. AsynchRunnable.java

package asyncpackage;

import javax.servlet.AsyncContext;

public class AsynchRunnable implements Runnable {

AsyncContext ctx;

public AsynchRunnable(AsyncContext ctx) {
this.ctx = ctx;
}

public void run() {
// Simulate a long-running task such as
// calling a webservice, performing database
// operation, or waiting for a server side
// event (such as receiving a message in
// Comet-enabled environment.
try {
// Sleep for 1000 ms
Thread.sleep(1000);
} catch (Exception ie) {
}

ctx.dispatch(“/response.jsp”);
}
}

AsynchRunnable.java

(5.3) Open, build, and run “servlet3.0_async_simple_complete” sample application (from “lab samples”)

1. Open servlet3.0_async_simple_complete NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/samples directory.
  • Select servlet3.0_async_simple_complete.
  • Click Open Project.
  • Observe that the servlet3.0_async_simple_complete project node appears under Projects tab window.

2. Build and run servlet3.0_async_simple_complete project.

  • Right-click servlet3.0_async_simple_complete project and select Run.
  • Observe that browser gets displayed.

(5.4) Study code

1. AsynchRunnable.java

package asynpackage;

importjavax.servlet.AsyncContext;

public class AsyncRunnable implements Runnable {

AsyncContext ctx;

public AsyncRunnable(AsyncContext ctx) {
this.ctx = ctx;
}

public void run() {
// Simulate a long-running task such as
// calling a webservice, performing database
// operation, or waiting for a server side
// event (such as receiving a message in
// Comet-enabled environment).
try {
// Sleep for 1000 ms
Thread.sleep(1000);
} catch (Exception ie) {
}

// Complete the asynch task
ctx.complete();
}
}

2. AsyncServlet.java

package asynpackage;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.servlet.AsyncContext;

@WebServlet(urlPatterns = “/AsyncServlet”, asyncSupported = true)
public class AsyncServlet extends HttpServlet {

@Override;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

AsyncContext aCtx = request.startAsync(request, response);
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.execute(new AsyncRunnable(aCtx));

// Control is returned after an async. call is done
response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {

out.println(“<html>”);
out.println(“<head>”);
out.println(“<title>Servlet NewServlet</title>”);
out.println(“</head>”);
out.println(“<body>”);
out.println(“<h1>Async. call is completed. ” +  “</h1>”);
out.println(“</body>”);
out.println(“</html>”);

} finally {
out.close();
}

}
}

AsyncServlet.java

(5.5) Open, build, and run “servlet3.0_async_simple_listener_completed” sample application (from “lab samples”)

1. Open servlet3.0_async_simple_listener_completed NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/samples directory.
  • Select servlet3.0_async_simple_listener_completed.
  • Click Open Project.
  • Observe that the servlet3.0_async_simple_listener_completed project node appears under Projects tab window.

2. Build and run servlet3.0_async_simple_listener_completed project.

  • Right-click servlet3.0_async_simple_listener_completed project and select Run.
  • Observe that browser gets displayed.


Figure-5.51


Figure-5.52

  • Observe in the GlassFish log that the onComplete() method is called.


Figure-5.52b

(5.6) Study code

1. AsyncServlet.java

package asyncpackage;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;

@WebServlet(urlPatterns = “/AsyncServlet”, asyncSupported = true)
public class AsyncServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

AsyncContext aCtx = request.startAsync(request, response);
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.execute(new AsyncRunnable(aCtx));

aCtx.addListener(new AsyncListener() {

public void onComplete(AsyncEvent event) throws IOException {
System.out.println(“—-onComplete() is called”);
}

public void onTimeout(AsyncEvent event) throws IOException {
System.out.println(“—-onTimeout() is called”);

}

public void onError(AsyncEvent event) throws IOException {
System.out.println(“—-onError() is called”);

}

public void onStartAsync(AsyncEvent event) throws IOException {
System.out.println(“—-onStartAsync() is called”);
}
});

// Control is returned after an async. call is done
response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {

out.println(“<html>”);
out.println(“<head>”);
out.println(“<title>Servlet NewServlet</title>”);
out.println(“</head>”);
out.println(“<body>”);
out.println(“<h1>Async call is done.” + “</h1>”);
out.println(“</body>”);
out.println(“</html>”);

} finally {
out.close();
}

}
}

(5.7) Open, build, and run “servlet3.0_async_simple_listener_timeout” sample application (from “lab samples”)

1. Open servlet3.0_async_simple_listener_timeout NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/samples directory.
  • Select servlet3.0_async_simple_listener_timeout.
  • Click Open Project.
  • Observe that the servlet3.0_async_simple_listener_timeout project node appears under Projects tab window.

2. Build and run servlet3.0_async_simple_listener_timeout project.

  • Right-click servlet3.0_async_simple_listener_timeout project and select Run.
  • Observe that browser gets displayed.


Figure-5.71


Figure-5.72

  • Observe in the GlassFish log that onTimeout() is first called, because it has been set shorter than the duration of the asynchroneous call, then onComplete() method is called.


Figure-5.72b

(5.8) Study code

1. AsyncServlet.java
package asynpackage;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;

@WebServlet(urlPatterns = “/AsyncServlet”, asyncSupported = true)
public class AsyncServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

AsyncContext aCtx = request.startAsync(request, response);
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.execute(new AsyncRunnable(aCtx));

// Add timeout less than the duration of Asynch call
aCtx.setTimeout(500);

aCtx.addListener(new AsyncListener() {

public void onComplete(AsyncEvent event) throws IOException {
System.out.println(“—-onComplete() is called”);
}

public void onTimeout(AsyncEvent event) throws IOException {
System.out.println(“—-onTimeout() is called”);

}

public void onError(AsyncEvent event) throws IOException {
System.out.println(“—-onError() is called”);

}

public void onStartAsync(AsyncEvent event) throws IOException {
System.out.println(“—-onStartAsync() is called”);
}
});

// Control is returned after an async. call is done
response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {

out.println(“<html>”);
out.println(“<head>”);
out.println(“<title>Servlet NewServlet</title>”);
out.println(“</head>”);
out.println(“<body>”);
out.println(“<h1>Async call is done.” + “</h1>”);
out.println(“</body>”);
out.println(“</html>”);

} finally {
out.close();
}

}
}

AsyncServlet.java

 

(5.9) Open, build, and run “async-request-war” sample application (from “lab samples”)

The “async-request-war” sample application is a chat application  where multiple users are participating in a chat.  This shows how Asynch. Servlet is used to support Comet.

1. Open async-request-war NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/samples directory. (Note: The async-request-war project in  <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/web/servlet directory has a bug, that causes Safari to misbehave.)
  • Select async-request-war.
  • Click Open Project.
  • Observe that the async-request-war project node appears under Projects tab window.

2. Build and run async-request-war project.

  • Right-click async-request-war project and select Run.
  • Observe that the default browser gets displayed.
3. Start the chatting from a user #1.
  • For Please input your name field, enter <your name>, Sang Shin in this example.
  • Click Login.

Figure-5.91

  • Observe that the System Message indicating that you have joined the chat.
  • Enter a message and click Post Message.


Figure-5.92

  • Observe that the message has been received.


Figure-5.93

4. Start the chatting from a user #2.

  • Open another browser type.  (If you were using Firefox for user #1, open either IE or Safari or Chrome, Opera for example.   If you were using Firefox for user #1 and want to use Firefox for the user #2, you have to start it from a different profile.  In this example, Safari is used.)
  • In the URL field, enter http://localhost:8080/async-request-war/ and click Return.


Figure-5.94

  • Observe that Login page appears.
  • For Please input your name field, enter a name of your friend, Arun Gupta in this example.
  • Click Login.

  • Observe that a message indicating Arun Gupta has joined chat gets displayed.


Figure-5.95

5. Go to the User #1 browser.

  • Observe that Arun Gupta has joined the chat.


Figure-9.96

6. Enter a message from User #2.


Figure-5.97

7. Observe the message posted by User #2 in User #1.


Figure-9.98

(5.10) Study the code

1. AjaxCometServlet.java.

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only (“GPL”) or the Common Development
* and Distribution License(“CDDL”) (collectively, the “License”).  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the “Classpath” exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: “Portions Copyrighted [year]
* [name of copyright owner]”
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding “[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license.”  If you don’t indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package web.servlet.async_request_war;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* This class illustrates the usage of Servlet 3.0 asynchronization APIs.
* It is ported from Grizzly Comet sample and use Servlet 3.0 API here.
*
* @author Shing Wai Chan
* @author JeanFrancois Arcand
*/
@WebServlet(urlPatterns = {“/chat”}, asyncSupported = true)
public class AjaxCometServlet extends HttpServlet {

private static final Queue<AsyncContext> queue = new ConcurrentLinkedQueue<AsyncContext>();

private static final BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();

private static final String BEGIN_SCRIPT_TAG = “<script type=’text/javascript’>\n”;

private static final String END_SCRIPT_TAG = “</script>\n”;

private static final long serialVersionUID = -2919167206889576860L;

private static final String JUNK = “<!– Comet is a programming technique that enables web ” +
“servers to send data to the client without having any need ” +
“for the client to request it. –>\n”;

private Thread notifierThread = null;

@Override
public void init(ServletConfig config) throws ServletException {
// When this Runnable class gets started as a long running thread,
// it continuously extracts posted messages from the message queue
// and sends them to all clients participating in the chat.
//
// Each client is represented as a separate AsyncContext
// object in the Queue<AsyncContext> queue.  When a new
// client joined the chat (accessing the application for the
// first time through HTTP GET), a new AsynchContext object gets
// created and saved in the Queue<AsyncContext> queue.
Runnable notifierRunnable = new Runnable() {
public void run() {
boolean done = false;
while (!done) {
String cMessage = null;
try {
cMessage = messageQueue.take();
for (AsyncContext ac : queue) {
try {
PrintWriter acWriter = ac.getResponse().getWriter();
acWriter.println(cMessage);
acWriter.flush();
} catch(IOException ex) {
System.out.println(ex);
queue.remove(ac);
}
}
} catch(InterruptedException iex) {
done = true;
System.out.println(iex);
}
}
}
};

// Start the thread as part of Servlet initialization
notifierThread = new Thread(notifierRunnable);
notifierThread.start();
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType(“text/html”);
res.setHeader(“Cache-Control”, “private”);
res.setHeader(“Pragma”, “no-cache”);

PrintWriter writer = res.getWriter();
// for Safari, Chrome, IE and Opera
for (int i = 0; i < 10; i++) {
writer.write(JUNK);
}
writer.flush();

// When a new client joined the chat, a new AsyncContext
// object is created and saved in the Queue<AsyncContext> queue.
// The AsyncContext object will be removed only when asynch.
// task is completed or timed out.
final AsyncContext ac = req.startAsync();
ac.setTimeout(10  * 60 * 1000);
ac.addListener(new AsyncListener() {
public void onComplete(AsyncEvent event) throws IOException {
System.out.println(“—-onComplete() of asynch-request-war is called”);
queue.remove(ac);
}

public void onTimeout(AsyncEvent event) throws IOException {
System.out.println(“—-onTimeout() of asynch-request-war is called”);
queue.remove(ac);
}

public void onError(AsyncEvent event) throws IOException {
System.out.println(“—-onError() of asynch-request-war is called”);
queue.remove(ac);
}

public void onStartAsync(AsyncEvent event) throws IOException {
System.out.println(“—-onStartAsync() of asynch-request-war is called”);
}
});
queue.add(ac);
}

@Override
@SuppressWarnings(“unchecked”)
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType(“text/plain”);
res.setHeader(“Cache-Control”, “private”);
res.setHeader(“Pragma”, “no-cache”);

req.setCharacterEncoding(“UTF-8”);
String action = req.getParameter(“action”);
String name = req.getParameter(“name”);

// When a login or message post request is received, call notify() method,
// which saves the message in the message queue.
if (“login”.equals(action)) {
String cMessage = BEGIN_SCRIPT_TAG + toJsonp(“System Message”, name + ” has joined.”) + END_SCRIPT_TAG;
notify(cMessage);

res.getWriter().println(“success”);
} else if (“post”.equals(action)) {
String message = req.getParameter(“message”);
String cMessage = BEGIN_SCRIPT_TAG + toJsonp(name, message) + END_SCRIPT_TAG;
notify(cMessage);

res.getWriter().println(“success”);
} else {
res.sendError(422, “Unprocessable Entity”);
}
}

@Override
public void destroy() {
queue.clear();
notifierThread.interrupt();
}

private void notify(String cMessage) throws IOException {
try {
messageQueue.put(cMessage);
} catch(Exception ex) {
IOException t = new IOException();
t.initCause(ex);
throw t;
}
}

private String escape(String orig) {
StringBuffer buffer = new StringBuffer(orig.length());

for (int i = 0; i < orig.length(); i++) {
char c = orig.charAt(i);
switch (c) {
case ‘\b’:
buffer.append(“\\b”);
break;
case ‘\f’:
buffer.append(“\\f”);
break;
case ‘\n’:
buffer.append(“<br />”);
break;
case ‘\r’:
// ignore
break;
case ‘\t’:
buffer.append(“\\t”);
break;
case ‘\”:
buffer.append(“\\'”);
break;
case ‘\”‘:
buffer.append(“\\\””);
break;
case ‘\\’:
buffer.append(“\\\\”);
break;
case ‘<‘:
buffer.append(“&lt;”);
break;
case ‘>’:
buffer.append(“&gt;”);
break;
case ‘&’:
buffer.append(“&amp;”);
break;
default:
buffer.append(c);
}
}

return buffer.toString();
}

private String toJsonp(String name, String message) {
return “window.parent.app.update({ name: \”” + escape(name) + “\”, message: \”” + escape(message) + “\” });\n”;
}
}

AjaxCometServlet.java

Summary

In this exercise,  you have learned how to use  asynch. Servlet API so that, a servlet no longer has to wait for a response from a resource such as a database before its thread can continue processing.

Exercise 6: File upload support

In this exercise, you are going to build, run, and study the “multipart-war” sample application, which demonstrates multipart (a.k.a. file upload) support.

  1. Open, build, and run “multipart-war” sample application.
  2. Study the code.

 

(6.1) Open, build, and run “multipart-war” sample application

1. Open multipart-war NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/web/servlet directory.
  • Select multipart-war.
  • Click Open Project.
  • Observe that the multipart-war project node appears under Projects tab window.

2. Build and run multipart-war project.

  • Right-click multipart-war project and select Run.
  • Browser gets displayed.


Figure-6.11

  • Click on the first Browse… button and navigate to <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/files directory.
    Choose billofrights.txt as first file to upload.
  • Click on the second Browse… button and choose binary.png in the same directory as second file to upload.
  • Click on the upload button.


Figure-6.11a

  • Observe that the server returns in a jsp page the multiparts of the uploaded files.


Figure-6.11b

  • Now, uncomment in getParts.jsp, the snippet of code which allows to dump a text file inside the jsp page.


Figure-6.11c

  • Click Save all button.
  • Click on the back button in the browser, then on the Reset button.
  • Choose the same text file as you have chosen previously as the first file to load and click on upload.


Figure-6.11d

  • Observe that the server dumps also the contents of the text file in the jsp page.


Figure-6.11e

(6.2) Study the code

1. Study index.html.

<html>
<head>
<title>File Upload Example</title>
</head>

<body>
<form action=”getParts.jsp” method=”post”
enctype=”multipart/form-data”>
<h3>Choose files to upload.</h3>
<input name=”myFile” size=”60″ type=”file”/> <br/>
<input name=”myFile2″ size=”60″ type=”file”/> <br/> <br/>
<input value=”upload” type=”submit”/>
<input type=”reset”/> <br/>
</form>
</body>
</html>

2. Study getParts.jsp.

<%@ page import=”javax.servlet.http.Part” %>

<html>
<head>
<title>File Upload Example</title>
</head>

<body>
<h1>Files Received at the Server</h1>
<br/>

<%
for (Part p: request.getParts()) {

/* out.write(“Part: ” + p.toString() + “<br/>\n”); */
out.write(“Part name: ” + p.getName() + “<br/>\n”);
out.write(“Size: ” + p.getSize() + “<br/>\n”);
out.write(“Content Type: ” + p.getContentType() + “<br/>\n”);
out.write(“Header Names:”);
for (String name: p.getHeaderNames()) {
out.write(” ” + name);
}
out.write(“<br/><br/>\n”);

/*
* If the part is a text file, the following code can be added to read
* the uploaded file, and dumps it on the response.

java.io.InputStreamReader in =
new java.io.InputStreamReader(p.getInputStream());

int c = in.read();
while (c != -1) {
if (c == ‘\n’) out.write(“<br/>”);
out.write(c);
c = in.read();
}
*/

}
%>

</body>
</html>

getParts.jsp.

3. Study the Javadoc of the HttpServletRequest class.


Figure-6.12

Summary

In this exercise,  you have learned how to multi-part methods of HttpServletRequest class.

 

Exercise 7: Build and run “sessioncookieconfig-war” sample application

In this exercise, you are going to build, run, study, and modify the “sessioncookieconfig-war” sample application, which demonstrates the new programmatic configuration support for session cookies available with Servlet 3.0.

  1. Open, build, and run “sessioncookieconfig-war” sample application
  2. Study the code

 

(7.1) Open, build, and run “sessioncookieconfig-war” sample application (from “glassfish-samples”)

1. Open sessioncookieconfig-war NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/web/servlet directory.
  • Select sessioncookieconfig-war.
  • Click Open Project.
  • Observe that the sessioncookieconfig-war project node appears under Projects tab window.

2. Build and run sessioncookieconfig-war project.

  • Right-click sessioncookieconfig-war project and select Run.
  • Browser gets displayed.


Figure-7.11

(7.2) Study the code

1. CreateSession.java.

package web.servlet.sessioncookieconfig_war;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CreateSession extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

req.getSession(true);

String sessionCookie = res.getHeader(“Set-Cookie”);
if (sessionCookie == null) {
throw new ServletException(“Missing Set-Cookie response header”);
}

// name
if (sessionCookie.indexOf(“MYJSESSIONID=”) == -1) {
throw new ServletException(“Missing session id”);
}

// comment
if (sessionCookie.indexOf(“Comment=myComment”) == -1) {
throw new ServletException(“Missing cookie comment”);
}

// domain
if (sessionCookie.indexOf(“Domain=mydomain”) == -1) {
throw new ServletException(“Missing cookie domain”);
}

// path
if (sessionCookie.indexOf(“Path=/myPath”) == -1) {
throw new ServletException(“Missing cookie path”);
}

// secure
if (sessionCookie.indexOf(“Secure”) == -1) {
throw new ServletException(“Missing Secure attribute”);
}

// http-only
if (sessionCookie.indexOf(“HttpOnly”) == -1) {
throw new ServletException(“Missing HttpOnly attribute”);
}

// max-age
if (sessionCookie.indexOf(“Max-Age=123”) == -1) {
throw new ServletException(“Missing max-age”);
}

res.getWriter().println(“SUCCESS”);
}
}

2. ConfigListener.java.

package web.servlet.sessioncookieconfig_war;

import java.io.*;
import java.util.*;
import javax.servlet.*;

public class ConfigListener implements ServletContextListener {

/**
* Receives notification that the web application initialization
* process is starting.
*
* @param sce The servlet context event
*/
public void contextInitialized(ServletContextEvent sce) {
SessionCookieConfig scc =
sce.getServletContext().getSessionCookieConfig();
scc.setName(“MYJSESSIONID”);
scc.setPath(“/myPath”);
scc.setDomain(“mydomain”);
scc.setComment(“myComment”);
scc.setSecure(true);
scc.setHttpOnly(true);
scc.setMaxAge(123);
}

/**
* Receives notification that the servlet context is about to be shut down.
*
* @param sce The servlet context event
*/
public void contextDestroyed(ServletContextEvent sce) {
// Do nothing
}
}

Summary

In this exercise,  you have learned how to use the new programmatic configuration support for session cookies available with Servlet 3.0.

Exercise 8: Security

In this exercise, you are going to build, run, study, and modify the “programmatic-login” sample application, which demonstrates the programmatic security (login/logout) feature in Servlets 3.0.

Programmatic security is used by security aware applications when declarative security alone is not sufficient to express the security model of the application. Programmatic security consists of the following methods of the HttpServletRequest interface:

  • login
  • logout
  • getRemoteUser
  • isUserInRole
  • getUserPrincipal
The login methods allow an application to perform username and password collection (as an alternative to Form-Based Login in previous versions of servlets), and to instigate authentication of the request caller by the container from within an unconstrained request context. The logout method is provided to allow an application to reset the caller identity of a request.

For detailed description of this tutorial, please see “Using Programmatic Security with Web Applications” section of the “Java EE 6 tutorial”.

 

 

(8.0)  Update the password of the “javaee6user” in the File-based security realm of the GlassFish v3

Depending on the system, the “javaee6user” exists or does not exist in the File-based security realm of the GlassFish v3 as part of GlassFish v3 installation.  The File-based security realm is the default security realm.

1.  Start GlassFish v3 Domain.

  • Select Services tab.
  • Expand Servers.
  • Right click GlassFish v3 Domain and select Start.

2.  Open GlassFish v3 Admin console.

  • Select Services tab.
  • Expand Servers.
  • Right click GlassFish v3 Domain and select View Admin Console.

Figure-8.01

3. Open Manage Users page.

  • Expand Security->Realms.
  • Click file security realm and observe that  Edit Realm pane appears on the right.
  • Click Manage Users.


Figure-8.02

4. Create the javaee6user if it does not exist.

Do not do this step if the javaee6user exists.

  • Observe that there is no user in the File Users database.
  • Click New….


Figure-8.02a

  • Enter javaee6user in the User ID field.
  • Enter javaee6user in the Group List field.
  • Enter test (or whatever you want) in the New Password field.
  • Enter test (or whatever you chose above) in the Confirm New Password field.
  • Click OK.


Figure-8.02b

5. Update the password of the javaee6user.

Do not do this step if you have done step 4.

  • Observe that the javaee6user user is already created.
  • Click javaee6user.


Figure-8.03

  • For the New Password and Confirm New Password fields, enter test (or whatever password of your choice).
  • Click Save.


Figure-8.04

(8.1) Open, build, and run “programmatic-login” sample application (from “glassfish-samples”)

1. Open programmatic-login NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/security directory.
  • Select programmatic-login.
  • Click Open Project.
  • Observe that the programmatic-login project node appears under Projects tab window.

2. Build and run programmatic-login project.

  • Right-click programmatic-login project and select Run.
  • Browser gets displayed.
  • For the Username field, enter javaee6user.
  • For the Password field, enter test (or whatever password you chose).


Figure-8.11


Figure-8.12

return to top of the exercise

(8.2) Study code

1. LoginServlet.java

package enterprise.programmatic_login;

import java.io.*;
import java.net.*;

import javax.annotation.security.DeclareRoles;
import javax.servlet.*;
import javax.servlet.http.*;

/**
*
* @author nithyasubramanian
*/
@DeclareRoles(“javaee6user”)
public class LoginServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {
String userName = request.getParameter(“txtUserName”);
String password = request.getParameter(“txtPassword”);

out.println(“Before Login”+”<br><br>”);
out.println(“IsUserInRole?..” + request.isUserInRole(“javaee6user”)+”<br>”);
out.println(“getRemoteUser?..” + request.getRemoteUser()+”<br>”);
out.println(“getUserPrincipal?..” + request.getUserPrincipal()+”<br>”);
out.println(“getAuthType?..” + request.getAuthType()+”<br><br>”);

try {
request.login(userName, password);
}catch(ServletException ex) {
out.println(“Login Failed with a ServletException..” + ex.getMessage());
return;
}
out.println(“After Login…”+”<br><br>”);
out.println(“IsUserInRole?..” + request.isUserInRole(“javaee6user”)+”<br>”);
out.println(“getRemoteUser?..” + request.getRemoteUser()+”<br>”);
out.println(“getUserPrincipal?..” + request.getUserPrincipal()+”<br>”);
out.println(“getAuthType?..” + request.getAuthType()+”<br><br>”);

request.logout();
out.println(“After Logout…”+”<br><br>”);
out.println(“IsUserInRole?..” + request.isUserInRole(“javaee6user”)+”<br>”);
out.println(“getRemoteUser?..” + request.getRemoteUser()+”<br>”);
out.println(“getUserPrincipal?..” + request.getUserPrincipal()+”<br>”);
out.println(“getAuthType?..” + request.getAuthType()+”<br>”);

} finally {
out.close();
}
}

// <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”>
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
*/
public String getServletInfo() {
return “Short description”;
}
// </editor-fold>
}

LoginServlet

(8.3) Open, build, and run “programmatic-authenticate” sample application (from “lab samples”)

1. Open programmatic-authenticate NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/samples directory.
  • Select programmatic-authenticate.
  • Click Open Project.
  • Observe that the programmatic-authenticate project node appears under Projects tab window.

2. Build and run programmatic-authenticate project.

  • Right-click programmatic-authenticate project and select Run.
  • Login dialog box gets displayed.
  • For the Username field, enter javaee6user.
  • For the Password field, enter test (or whatever password you chose).


Figure-8.31

Trouble-shooting: If you don’t see the dialog box above, it is highly likely because the browser cache the previous login name and password.  Close all browser instanced and run the program again.


Figure-8.32

(8.4) Study the code

1. AuthenticateServlet.java

package mypackage;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
*
* @author sang
*/
@WebServlet(name=”AuthenticateServlet”, urlPatterns={“/AuthenticateServlet”})
public class AuthenticateServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {
request.authenticate(response);
out.println(“Authenticate Successful”+”<br>”);
out.println(“IsUserInRole?..” + request.isUserInRole(“javaee6user”)+”<br>”);
out.println(“getRemoteUser?..” + request.getRemoteUser()+”<br>”);
out.println(“getUserPrincipal?..” + request.getUserPrincipal()+”<br>”);
out.println(“getAuthType?..” + request.getAuthType()+”<br>”);

} finally {
out.close();
}

}

// <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”>
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return “Short description”;
}// </editor-fold>

}

(8.5) Open, build, and run “http-method-omission” sample application (from “glassfish-samples”)

1. Open http-method-omission NetBeans project.

  • Select File->Open Project (Ctrl+Shift+O).
  • Observe that the Open Project dialog box appears.
  • Browse down to <GlassFish-v3-Installation-Directory>/glassfish/samples/javaee6/security directory.
  • Select http-method-omission.
  • Click Open Project.
  • Observe that the http-method-omission project node appears under Projects tab window.

2. Build and run http-method-omission project.

  • Right-click http-method-omission project and select Run.
  • Browser gets displayed.
  • Click Try Post button.


Figure-8.51

  • Observe that “Welcome javaee6user” message is displayed.


Figure-8.52

  • Click Backward button of the browser.
  • Click Try Get button.


Figure-8.53

  • Observe that the access is denied.  (This is expected behavior.)


Figure-8.54

(8.6) Study code

1. Index.jsp.

<html>

<body>
Test Http Method Omissions in Servlet
<br><br>
<form name=”formPost” action=”/http-method-omission/omissionservlet” method=”POST”>
The Post Method is permitted only for javaee6user<br>
<input type=”submit” value=”Try Post” />
</form>
<br><br>
<form name=”formGet” action=”/http-method-omission/omissionservlet” method=”GET”>
The Get method is denied access to all users <br>
<input type=”submit” value=”Try Get” />
</form>

</body>
</html>

index.jsp

2. OmissionServlet.java

package enterprise.http_method_omission;

import java.io.*;

import java.security.Principal;
import javax.servlet.*;
import javax.servlet.http.*;

/**
*
* @author nithyasubramanian
*/
public class OmissionServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Principal userPrincipal = request.getUserPrincipal();
String userName = userPrincipal.getName();

response.setContentType(“text/html;charset=UTF-8”);
PrintWriter out = response.getWriter();
try {
// TODO output your page here
out.println(“<html>”);
out.println(“<body>”);
out.println(“Welcome ” + userName);
out.println(“</body>”);
out.println(“</html>”);

} finally {
out.close();
}

}

// <editor-fold defaultstate=”collapsed” desc=”HttpServlet methods. Click on the + sign on the left to edit the code.”>
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}

OmissionServlet.java

2. web.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app version=”3.0″ xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd”>
<servlet>
<servlet-name>OmissionServlet</servlet-name>
<servlet-class>enterprise.http_method_omission.OmissionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OmissionServlet</servlet-name>
<url-pattern>/omissionservlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>OmissionConstraint</display-name>
<web-resource-collection>
<web-resource-name>resource1</web-resource-name>
<description/>
<url-pattern>/omissionservlet</url-pattern>
<http-method-omission>POST</http-method-omission>
</web-resource-collection>
<auth-constraint>
<description/>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>MethodConstraint</display-name>
<web-resource-collection>
<web-resource-name>resource1</web-resource-name>
<description/>
<url-pattern>/omissionservlet</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>javaee6user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name/>
</login-config>
<security-role>
<description/>
<role-name>javaee6user</role-name>
</security-role>
</web-app>

web.xml

Summary

In this exercise,  you have learned how to use programmatic security (login/logout) feature in Servlets 3.0.

 

Mandatory Homework Exercise (for people who are taking “Java EE 6 Codecamp”)

 

1. The homework is to modify helloservlet project as following.  The helloservlet project is provided under <LAB_UNZIPPED_DIRECTORY>/javaee6_servlet3.0/samples directory. (You might want to create a new project by copying helloservlet project.  You can name the newly copied project in any way you want.  Here it is referred to as myhelloservlet.)

  • Goal: exercising annotations
    • Remove web.xml.
    • Use @WebServlet annotation for the GreetingServlet.
    • Use dynamic registration for the ResponseServlet.
  • Goal: exercising 3rd party library/framework pluggability
    • Create a library called mywebfragment1 with its own web-fragment.xml.
    • Define a filter in which “myfiltermessage” attribute in the request scope is appended with a value “mymessage1”.  The filter configuration should be specified in the web-fragment.xml.
    • Create another library called mywebfragment2 without web-fragment.xml.  The filter configuration should be configured with @WebFilter annotation.
2. Send the following files to javaee6-homeworks@sun.com with Subject as homework_javaee6_servlet3.0.
  • Zip file of the the myhelloservlet NetBeans project.  (Someone else should be able to open and run it as a NetBeans project.)  You can use your favorite zip utility or you can use “jar” utility that comes with JDK as following.
    • cd <parent directory that contains myhelloservlet directory> (assuming you named your project as myhelloservlet)
    • jar cvf myhelloservlet.zip myhelloservlet (myhelloservlet should contain nbproject directory)
Or you can install Project Packager NetBeans plug-in (from http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=3742).  You can then export your project as a zip file – the build and dist directories are removed automatically to make the smaller zip file. If you set up SMTP, you can even e-mail your zipped project to someone.
  • Captured output screen  – name it as homework_javaee6_servlet3.0.gif or homework_javaee6_servlet3.0.jpg (or homework_javaee6_servlet3.0.<whatever graphics format>)
    • Any screen capture that shows that your program is working is good enough.

Optional Homework Exercise (for people who are taking “Java EE 6 Codecamp”)

 

 You don’t need to submit optional homework exercise unless you want to.

 

1. The homework is to modify async-request-war project as following.   (You might want to create a new project by copying async-request-war project.  You can name the newly copied project in any way you want.  Here it is referred to as my-async-request-war.)

  • Add a “Quit chatting” button, when pressed, to close a chatting session.
  • Add a “Restart chatting” button, when pressed, to restart a chatting session
2. Send the following files to javaee6-homeworks@sun.com with Subject as homework_javaee6_servlet3.0-optional.
  • Zip file of the the my-async-request-war NetBeans project.  (Someone else should be able to open and run it as a NetBeans project.)  You can use your favorite zip utility or you can use “jar” utility that comes with JDK as following.
    • cd <parent directory that contains my-async-request-war directory> (assuming you named your project as my-async-request-war)
    • jar cvf my-async-request-war.zip my-async-request-war (my-async-request-war should contain nbproject directory)

 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.