Using Servlets and JavaServer Pages with Portlets

40 401 0
Using Servlets and JavaServer Pages with Portlets

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

119 CHAPTER 5 Using Servlets and JavaServer Pages with Portlets T HE PORTLET APPLICATION can use servlets and JavaServer Pages (JSP) in addition to portlets. These Java 2 Enterprise Edition (J2EE) resources can be created espe- cially for the portlet application, or they can be part of a port of an existing J2EE application. Existing servlets and JSP will probably need to be edited to conform to the portlet markup rules for a content fragment. In this chapter, we discuss using servlets and JSP with a portlet. Most portlets will use JSP or another page display technology such as Apache Velocity to render content. Rendering content directly from a portlet is just as awkward as displaying HTML output from a servlet. This chapter also examines using the portlet request dispatcher, which is used to include servlets or JSP inside the portlet. The portlet passes its render request and response objects to the servlet or JSP, and we cover the rules and exceptions for this pass-through. In addition, we explain how to handle any exceptions the servlet might throw inside the portlet. You’ll also learn how to deploy servlets, JSP, and portlets together as an integrated web application. We are not going to cover any web frameworks in this chapter. Apache Struts 2.0 and JavaServer Faces (JSF) will support portlet applications in the future. Most popular open source frameworks will probably release a portlet module or add-on. The biggest architectural difference is that portlets have to handle two requests (action and render) instead of just one (like a web application). Portlets, Servlets, and JSP Design Goals Most portlets should use JSP or another presentation technology (like Apache Velocity) to display their content The JSP page can share the portlet’s session, request, and response objects easily, and there is a portlet JSP tag library to make some tasks easy. In these cases, the portlet is going to act as a controller, and handle incoming action and render requests. The render requests will be processed and delegated 2840ch05.qxd 7/13/04 12:44 PM Page 119 Download at Boykma.Com Chapter 5 120 to a JSP page, based on session attributes, request parameters, portlet modes, or window states. The action request handling phase of the portlet makes an excellent place to put a front controller that handles incoming command requests, while the render() method can determine which page to display. The business logic for the portlet application should be encapsulated in classes that do not refer to classes from the javax.portlet package. This makes reuse easier in web applications, Swing applications, web services, or other portlet applications. One factor to consider when assessing JSP reuse is that the portlet should be using styles defined in the portal’s style sheet for all content. If your content all shares a similar look and feel across portlets, it makes the portal seem more inte- grated, and portal administrators can adjust the portal style sheet to reflect desired changes. These changes could include standard fonts, company colors, or larger default text sizes. If you reuse these JSP pages in a standard web application, you will need to have your own copy of a portlet-API compatible style sheet in the web application, to match the expected styles. You also will have to be careful not to use portlet tags or classes inside the JSP if you want it to remain portable. For these reasons, it is probably not likely that you will be able to leverage much of the JSP pages directly for reuse. Some pages may lend themselves better than others. Try and encapsulate some common functional- ity into a JSP tag library that can be shared between different applications. Split the JSP pages into chunks of portable and nonportable code. For exceptionally large applications (hundreds or even thousands of pages), you may want to look into a page-generation technology with templates. Using Apache Velocity ( http://jakarta.apache.org/velocity ) or another page template language, you could define certain chunks of the templates as portlet code and other parts as web application code. A simple generation tool that calls Velocity could generate JSP pages for both portlets and web applications, and store them in different folders. You could also use Velocity directly within a portlet, instead of JSP. Portlet Request Dispatcher Your portlet can use a portlet request dispatcher to include the content from a servlet or JSP page. The portlet request dispatcher translates the portlet’s render request and render response into servlet requests and responses. Then the portlet request dispatcher passes those servlet objects to the appropriate servlet or JSP resource. The resource processes the render request as if the request was an HttpServletRequest and adds its content to the portlet’s render response. Each portlet has access to a portlet request dispatcher through the portlet’s PortletContext object. The portlet request dispatcher is an object the portlet container creates that implements the PortletRequestDispatcher interface. Here are the two methods for retrieving a PortletRequestDispatcher object from the PortletContext object: 2840ch05.qxd 7/13/04 12:44 PM Page 120 Download at Boykma.Com Using Servlets and JavaServer Pages with Portlets 121 public PortletRequestDispatcher getNamedDispatcher(String name) public PortletRequestDispatcher getRequestDispatcher(String path) Each of these methods retrieves a portlet request dispatcher for a servlet or JSP. The difference is how the resource is found in the web application. The getNamedDispatcher() method is used to get access to a servlet or JSP that is given a name in the web application deployment descriptor. It is also possible to name a servlet from your application server’s administration tool; this is dependent on the application server used. The getRequestDispatcher() method is used to access a resource relative to the portlet’s context root. The path argument must start with a “/”, and must be a valid path. For each of these methods, if the path or name is invalid, the methods will return null. The PortletRequestDispatcher object is very similar to the RequestDispatcher object from the servlet API. The major difference is that servlets may either include another servlet or forward a request, while portlets may only include another servlet’s response. A portlet may not forward a request to a servlet, because that means that control would not return to the portlet. The portlet remains in control when it includes a servlet or a JSP. When the servlet (or JSP) is finished writing output, con- trol passes back to the portlet that included the servlet. There is only one method on the PortletRequestDispatcher object: public void include(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException The include() method hides all of the details of loading and processing the servlet or JSP page, just like in the servlet API. Request Dispatcher A portlet may use a portlet request dispatcher to include the output of either a servlet or a JSP page. This example shows how to load a JSP page called homePage.jsp from the WEB-INF/jsp directory of your portlet application: PortletContext portletContext = getPortletContext(); PortletRequestDispatcher prd =➥ PortletContext.getRequestDispatcher("/jsp/homePage.jsp"); prd.include(request,response); The include() method on the PortletRequestDispatcher object throws a PortletException or an IOException . You may pass a query string on the path used for the getRequestDispatcher() method. For instance, our previous example could look like this: 2840ch05.qxd 7/13/04 12:44 PM Page 121 Download at Boykma.Com Chapter 5 122 PortletContext portletContext = getPortletContext(); PortletRequestDispatcher prd =➥ PortletContext.getRequestDispatcher("/jsp/homePage.jsp?personalize=NONE"); prd.include(request,response); The rule to remember is that any parameters passed in the query string to the PortletRequestDispatcher override any existing parameters with the same name on the request object. This can be useful for providing temporary overrides of param- eters for one JSP page, while keeping the portlet’s parameters intact for use on other JSP pages and servlets. If you would like to load a servlet through a request dispatcher, map the servlet to a path in your portlet application’s web.xml deployment descriptor. Use the <servlet-mapping> element in the web.xml file, just as you would for a normal web application. Here is a snippet of code that includes a servlet with a request dispatcher: PortletContext portletContext = getPortletContext(); PortletRequestDispatcher prd =➥ portletContext.getRequestDispatcher("/patents"); prd.include(request,response); Named Dispatcher A named dispatcher is useful for loading servlets or JSP pages that have been given a name in the portlet application’s web deployment descriptor. It also returns a PortletRequestDispatcher object. One important difference is that it is impossible to pass a query string to a servlet or JSP that is called through a named dispatcher. If we have a servlet named SingleSignOnServlet, we could include it when we render the portlet, using code like the following: PortletContext portletContext = getPortletContext(); PortletRequestDispatcher prd =➥ PortletContext.getNamedDispatcher("SingleSignOnServlet"); prd.include(request,response); One important point is that portlets may not be included in the output of another portlet using dispatchers. Rendering one portlet’s content inside another portlet should be accomplished by calling methods directly to get content, providing access to the portlet’s templates, or another form of direct access. 2840ch05.qxd 7/13/04 12:44 PM Page 122 Download at Boykma.Com Using Servlets and JavaServer Pages with Portlets 123 Including Content in the Portlet The content returned by a servlet should be the same type of content that the portlet is writing out. In almost all cases, that will be character data, not binary data. If you need to serve binary data from a portlet, provide a link directly to the servlet from the portlet’s content. This way, your portlet application can serve images, PDF files, and other binary data. For character data, use the getWriter() method on the servlet response. Your servlet should not try to set the content type on its servlet response. The portlet is in control of the content type, and the servlet cannot affect it. Although your portlet sets the content type on its response, your servlet cannot get the con- tent type from the servlet request. If your servlet works with different types of text content (XML, HTML, etc.), you will need to manage content types with request attributes or session parameters. You can always use two different servlet classes, of course. Handling Exceptions Thrown by the Servlet or JSP Portlets will need to be able to handle exceptions thrown by servlets or JSP pages that are included by the portlet. If the servlet or JSP throws an IOException , the IOException is passed unchanged to the portlet. Every other type of exception is encapsulated in a PortletException by the portlet container. Either the portlet may catch these exceptions itself, or it may throw them to the portlet container, just like any other type of portlet exception. Simple Portlet Example That Includes a Servlet We are going to demonstrate how to include a servlet inside a portlet, using the named dispatcher and the request dispatcher. For simplicity, we are going to have only one servlet, and it is going to write only one line of content. We will include it once with a request dispatcher, and once with a named dispatcher. When you run this simple HelloPortlet example in Pluto, it will look like Figure 5-1. 2840ch05.qxd 7/13/04 12:44 PM Page 123 Download at Boykma.Com Chapter 5 124 The servlet is named HelloServlet in the web application deployment descriptor, and it is mapped to the /hello URL. Here is the web.xml deployment descriptor for our portlet application, with the servlet description and mapping: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>First Portlet</display-name> <description>This is the first portlet.</description> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.portalbook.servlets.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app> The HelloPortlet class is very simple. You can see how it sets up both of the portlet request dispatchers: Figure 5-1. Our HelloPortlet example showing two types of request dispatches to a servlet 2840ch05.qxd 7/13/04 12:44 PM Page 124 Download at Boykma.Com Using Servlets and JavaServer Pages with Portlets 125 package com.portalbook.portlets; import java.io.IOException; import javax.portlet.GenericPortlet; import javax.portlet.PortletContext; import javax.portlet.PortletException; import javax.portlet.PortletRequestDispatcher; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; public class HelloPortlet extends GenericPortlet { protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { response.setContentType("text/html"); PortletContext portletContext = getPortletContext(); PortletRequestDispatcher reqDispatcher = portletContext.getRequestDispatcher("/hello"); reqDispatcher.include(request, response); PortletRequestDispatcher namedDispatcher = portletContext.getNamedDispatcher("HelloServlet"); namedDispatcher.include(request, response); } } Next is our HelloServlet class, which writes only one line to its response. We do not include a content type in its output because the portlet already did. package com.portalbook.servlets; import java.io.*; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { 2840ch05.qxd 7/13/04 12:44 PM Page 125 Download at Boykma.Com Chapter 5 126 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.write("<BR>Hello, I'm inside a portlet."); } } Our portlet.xml deployment descriptor is very ordinary because it does not describe anything about the servlet: <?xml version="1.0" encoding="UTF-8"?> <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"➥ version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"➥ xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd➥ http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"> <portlet> <description>Includes a Servlet</description> <portlet-name>HelloPortlet</portlet-name> <display-name>Hello Portlet</display-name> <portlet-class>com.portalbook.portlets.HelloPortlet</portlet-class> <expiration-cache>-1</expiration-cache> <supports> <mime-type>text/html</mime-type> <portlet-mode>VIEW</portlet-mode> </supports> <portlet-info> <title>Hello Portlet</title> <short-title>Hello</short-title> <keywords>Hello, Portlet</keywords> </portlet-info> </portlet> </portlet-app> Request and Response Objects The servlet or JSP that is included in the portlet’s render response has partial, limited access to the portlet’s RenderRequest and RenderResponse objects through the servlet or JSP’s HttpServletRequest and HttpServletResponse objects. Many of the servlet methods either perform no operation or return null when used inside a portlet, because portlets have a higher level of abstraction than servlets. Other servlet methods call the equivalent method on the portlet objects. Table 5-1 lists the methods on the HttpServletRequest , and how they behave when included from a portlet. 2840ch05.qxd 7/13/04 12:44 PM Page 126 Download at Boykma.Com Using Servlets and JavaServer Pages with Portlets 127 Table 5-1. The Methods on an HttpServletRequest Object in a Portlet Method Name Method Description getAttribute() Returns the value of an attribute when given a name, or null. Calls getAttribute() on the portlet’s PortletRequest object. getAttributeNames() Returns the names of the available attributes. Calls getAttributeNames() on the portlet’s PortletRequest object. getAuthType() Returns the authentication scheme used. Calls getAuthType() on the portlet’s PortletRequest object. getCharacterEncoding() Returns null; does nothing. getContentLength() Always returns 0. getContentType() Returns null; does nothing. getContextPath() Returns the context path associated with the portlet application on the portal. Calls getContextPath() on the portlet’s PortletRequest object. getCookies() Returns cookies from properties on the portlet request. getDateHeader() Returns a date header from properties on the portlet request. getHeader() Returns header from properties on the portlet request. getHeaderNames() Returns header names from properties on the portlet request. getHeaders() Returns headers from properties on the portlet request. getInputStream() Returns null; does nothing. getIntHeader() Returns an integer header from properties on the portlet request. getLocale() Returns preferred locale for the portal. Calls getLocale() on the portlet’s PortletRequest object. getLocales() Returns locales accepted by the portal. Calls getLocales() on the portlet’s PortletRequest object. getMethod() Returns “GET”. getParameter() Returns the value of the parameter from either the portlet request, or from the query string passed into the request dispatcher. The query string takes precedence. 2840ch05.qxd 7/13/04 12:44 PM Page 127 Download at Boykma.Com Chapter 5 128 Table 5-1. The Methods on an HttpServletRequest Object in a Portlet (continued) Method Name Method Description getParameterMap() Returns a map of name/value pairs of the parameters from the portlet request and the query string passed into the request dispatcher. The query string takes precedence. getParameterNames() Returns the names of the parameters from the portlet request and the query string passed into the request dispatcher. getParameterValues() Returns the values of the parameter from the portlet request and the query string passed into the request dispatcher. The query string takes precedence. getPathInfo() Returns the path and query used to get the portlet’s request dispatcher. getPathTranslated() Returns the path and query used to get the portlet’s request dispatcher. getProtocol() Returns null. getQueryString() Returns the path and query used to get the portlet’s request dispatcher. getReader() Returns null; does nothing. getRealPath() Returns null. getRemoteAddr() Returns null. getRemoteHost() Returns null. getRemoteUser() Returns the login for the current user, or null if there is no login yet. Calls getRemoteUser() on the portlet’s PortletRequest object. getRequestDispatcher() Same as Servlet 2.3 specification. getRequestedSessionId() Returns the request’s session ID, or null if there is none. Calls getRequestedSessionId() on the portlet’s PortletRequest object. getRequestURI() Returns the path and query used to get the portlet’s request dispatcher. getRequestURL() Returns null. getScheme() Returns the name of the URL scheme used to call the portlet. Calls getScheme() on the portlet’s PortletRequest object. getServerName() Returns the server’s hostname. Calls getServerName() on the portlet’s PortletRequest object. 2840ch05.qxd 7/13/04 12:44 PM Page 128 Download at Boykma.Com [...]... itself with data operations and page display dispatching In the next section, we discuss the JSP pages that display the content of the application We also briefly introduce the Java Standard Tag Library (JSTL), which we use in the JSP pages but that does not have anything to do with portals or portlets Using the Java Standard Tag Library (JSTL) We use the Java Standard Tag Library (JSTL) in our JSP pages. .. This attribute is also optional, and if it is omitted, the portlet will retain its current mode The portlet modes defined in the specification are VIEW, EDIT, and HELP You may also use any custom portlet modes that your portal supports Like window states, a nonvalid 134 Download at Boykma.Com 2840ch05.qxd 7/13/04 12:44 PM Page 135 Using Servlets and JavaServer Pages with Portlets portlet mode will result... /WEB-INF/tags/portlet.tld 132 Download at Boykma.Com 2840ch05.qxd 7/13/04 12:44 PM Page 133 Using Servlets and JavaServer Pages with Portlets You do not need to add anything to the portlet.xml deployment descriptor to enable the tag library, because the tags are for the JSP pages, which are processed by the JSP compiler and servlet engine The JSP Tag The tag is used to define... name="COMMAND" value="NEW"/> " 146 Download at Boykma.Com 2840ch05.qxd 7/13/04 12:44 PM Page 147 Using Servlets and JavaServer Pages with Portlets method="post"> Description: Figure 5-2 The VIEW mode for the to-do list portlet The homePage.jsp page uses an item from the portlet session and. .. href=" 148 Download at Boykma.Com 2840ch05.qxd 7/13/04 12:44 PM Page 149 Using Servlets and JavaServer Pages with Portlets " >(change) Incomplete . CHAPTER 5 Using Servlets and JavaServer Pages with Portlets T HE PORTLET APPLICATION can use servlets and JavaServer Pages (JSP) in addition to portlets. . 12:44 PM Page 124 Download at Boykma.Com Using Servlets and JavaServer Pages with Portlets 125 package com.portalbook .portlets; import java.io.IOException;

Ngày đăng: 05/10/2013, 04:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan