portlet

We’ve introduced all of these concepts that would be used while you’re dealing with the Portlet development. Portlet and Portlet container had used several objects that make obligation between both of them to get their functionality achieved.

我们介绍了在处理Portlet开发时将使用的所有这些概念。 Portlet和Portlet容器使用了多个对象,这两个对象之间都承担了义务,以实现其功能。

However, no one of these tutorials have provided you a full detailed explanation for these fine-grained objects. To get into real development, you should be aware of these objects as well as you must have to know what these objects are closely,  how can they are used and when their usage should be to get the most benefit.

但是,这些教程都没有一个为您提供这些细粒度对象的完整详细说明。 要进行真正的开发,您应该了解这些对象,还必须知道这些对象紧密相关,如何使用它们以及何时应使用它们才能获得最大收益。

Portlet教程 (Portlet Tutorial)

This tutorial intended to help you getting these information in an organised manner as it’s also will make you use all of them willingly. Following below core concepts that you would pass through:

本教程旨在帮助您以有组织的方式获取这些信息,因为它也会使您乐于使用所有这些信息。 遵循以下核心概念:

  • Portlet RequestsPortlet请求
  • Render Request渲染请求
  • Action Request行动要求
  • Portlet ResponsesPortlet响应
  • Render Response渲染响应
  • Action Response动作回应
  • Summary摘要

Portlet请求 (Portlet Requests)

As we’ve stated earlier, the PortletRequest interface represents the common functionality that’s lying in RenderRequest interface and ActionRequest interface as both of them have extended the PortletRequest interface.

如前所述,PortletRequest接口代表了RenderRequest接口和ActionRequest接口中的常用功能,因为它们都扩展了PortletRequest接口。

PortletRequest interface provides methods for accessing various types of needed information. These information would be:

PortletRequest接口提供了用于访问各种类型的所需信息的方法。 这些信息将是:

Request Attributes:  request attributes used mainly to pass Java objects between Portlets, Servlets and JSP pages. These attributes are formed as name/value pairs, in that the String will form the name of the attribute while Java Object is the value.

请求属性 :请求属性主要用于在Portlet,Servlet和JSP页面之间传递Java对象。 这些属性形成为名称/值对,因为String将形成属性的名称,而Java Object是值。

As soon as the Portlet receives a new action request, the attributes that were sent previously are no longer available and they will be replaced by new ones. The Portlet may set, update, delete and read attributes during action processing and render processing by invoking request.getAttribute(), request.setAttribute() and request.getAttributeNames().

Portlet收到新的操作请求后,先前发送的属性将不再可用,并且将被新的替换。 Portlet可以通过调用request.getAttribute()request.setAttribute()request.getAttributeNames()在操作处理和呈现处理期间设置,更新,删除和读取属性。

Basically, any attributes you’ve set against request while executing of processAction() phase won’t be available by the request object while executing of render() phase. Even Java Portlet Specification 2.0 has  provided the PLT.10.4.4 Runtime Option javax.portlet.actionScopedRequestAttributes that will make your processAction() attributes available while executing of render() phase but unfortunately this feature isn’t implemented in Apache Pluto 2.0.3 as you can refer for Apache Pluto’s JIRA.

基本上,您在执行processAction()阶段时针对请求设置的任何属性在执行render()阶段时都不能由请求对象使用。 甚至Java Portlet Specification 2.0也提供了PLT.10.4.4运行时选项javax.portlet.actionScopedRequestAttributes ,这些属性将使您的processAction()属性在执行render()阶段时可用,但是不幸的是,该功能未在Apache Pluto 2.0.3中实现。您可以参考Apache Pluto的JIRA 。

A more detailed sample would be discussed, especially when it comes to use the JSF bridge that already facilitate sending objects through using of request attributes.

我们将讨论一个更详细的示例,尤其是在使用JSF桥时,该桥已经通过使用请求属性方便了发送对象。

Request Parameters:  Request parameters aren’t so differ from discussed request attributes, they’re pairs of name/value where both of them are a String object. The most important issue here are the sources that request parameter come from. Typically, request parameters are those appended onto Portlet URL (e.g ActionURL, RenderURL), submitted by the form or set during execution of action request.

请求参数:   请求参数与讨论的请求属性没有太大区别,它们是一对名称/值,其中它们都是String对象。 这里最重要的问题是请求参数的来源。 通常,请求参数是那些附加到Portlet URL上的参数(例如ActionURLRenderURL ),由表单提交或在执行操作请求期间设置。

The parameters sent to the Portlet from an action request are valid only while the action request is processed. Meanwhile, the render parameters are valid until the Portlet has received a new request. According to Java Portlet Specification 2.0, all these requests that are responsible for change the Portlet’s window state or mode from the user interface elements on the Portal page shouldn’t reset the render parameters for the Portlet.

从动作请求发送到Portlet的参数仅在处理动作请求时才有效。 同时,渲染参数在Portlet收到新请求之前一直有效。 根据Java Portlet Specification 2.0,负责从门户网站页面上的用户界面元素更改Portlet窗口状态或模式的所有这些请求均不应重置Portlet的呈现参数。

Both of processAction() and render are read the request parameters using the same methods; getParamaterMap(), getParameter(), getParameterNames() and getParamaterValues() are used for this purpose. Following sample shows you how can we develop simple Login form where you must enter journaldev as a username and password to get logged into.

使用相同的方法读取processAction()和render的请求参数。 为此使用了getParamaterMap()getParameter()getParameterNames()getParamaterValues() 。 以下示例向您展示了如何开发简单的Login表单,您必须在其中输入journaldev作为用户名和密码才能登录。

package com.journaldev.portlet;import java.io.IOException;import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;public class RequestParameters extends GenericPortlet{public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {// Check if the loggedIn is null for initial stateif(request.getParameter("loggedIn") == null){response.getWriter().println("<form action="+response.createActionURL()+">"+ "Enter Username : <input type='text' id='username' name='username'/>"+ "Enter Password : <input type='password' id='password' name='password'/>"+ "<input type='submit' value='Login'/>"+ "</form>");   }else {// Get loggedIn value from the request parameterboolean loggedIn = Boolean.parseBoolean(request.getParameter("loggedIn"));if(loggedIn){response.getWriter().println("<form action="+response.createActionURL()+">"+ "<p>You're logged in</p>"+ "</form>");}else {response.getWriter().println("<form action="+response.createActionURL()+">"+ "<span style='color:red'>Try another</span><br/>"+ "Enter Username : <input type='text' id='username' name='username'/>"+ "Enter Password : <input type='password' id='password' name='password'/>"+ "<input type='submit' value='Login'/>"+ "</form>");         }   }   }public void processAction(ActionRequest request, ActionResponse response) throws PortletException {// Fetch username and password from the request parameters of actionString username = request.getParameter("username");String password = request.getParameter("password");// Do some checking procedureif(username != null && username.equals("journaldev") &&password != null && password.equals("journaldev")){// Use render parameters to pass the resultresponse.setRenderParameter("loggedIn", "true");}else {// Use render parameters to pass the resultresponse.setRenderParameter("loggedIn", "false");}}
}

portlet.xml

portlet.xml

<?xml version="1.0" encoding="UTF-8"?><portlet-app xmlns="https://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"version="2.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"><portlet><display-name>Request Attributes</display-name><portlet-name>requestAttributes</portlet-name><portlet-class>com.journaldev.portlet.RequestParameters</portlet-class><description>Print out all attributes located at the PortletRequest</description><portlet-info><title>Request Attributes</title><keywords>request, attributes</keywords><short-title>Request Attributes</short-title></portlet-info></portlet></portlet-app>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.journaldev</groupId><artifactId>PortletConcepts</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>PortletConcepts</name><url>https://maven.apache.org</url><properties><deployFolder>D:/Apache Pluto/pluto-2.0.3/webapps</deployFolder></properties><dependencies><!-- Java Portlet Specification V2.0 --><dependency><groupId>org.apache.portals</groupId><artifactId>portlet-api_2.0_spec</artifactId><version>1.0</version><scope>provided</scope></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><!-- bind 'pluto2:assemble' goal to 'process-resources' lifecycle --><!-- This plugin will read your portlet.xml and web.xml and injects required lines --><plugin><groupId>org.apache.portals.pluto</groupId><artifactId>maven-pluto-plugin</artifactId><version>2.1.0-M3</version><executions><execution><phase>generate-resources</phase><goals><goal>assemble</goal></goals></execution></executions></plugin><!-- configure maven-war-plugin to use updated web.xml --><!-- This plugin will make sure your WAR will contain the updated web.xml --><plugin><artifactId>maven-war-plugin</artifactId><version>2.1.1</version><configuration><webXml>${project.build.directory}/pluto-resources/web.xml</webXml></configuration></plugin><plugin><artifactId>maven-antrun-plugin</artifactId><executions><execution><id>copy</id><phase>integration-test</phase><configuration><tasks><copy file="target/${project.artifactId}.war" tofile="${deployFolder}/${project.artifactId}.war" /></tasks></configuration><goals><goal>run</goal></goals></execution><execution><id>delete</id><phase>clean</phase><configuration><tasks><delete file="${deployFolder}/${pom.build.finalName}.war" /><delete dir="${deployFolder}/${pom.build.finalName}" /></tasks><detail>true</detail></configuration><goals><goal>run</goal></goals>                       </execution>                  </executions></plugin>  <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></build>
</project>

Here’s detailed explanation for the code listed above:

这是上面列出的代码的详细说明:

  • You can use RenderResponse to create actionURL or renderURL.您可以使用RenderResponse创建actionURLrenderURL
  • It’s possible to pass the parameters as appended name/value into both of action request and render request.可以将参数作为附加的名称/值传递到动作请求和渲染请求中。
  • Action request has the ability to add any new parameters for render request.动作请求可以为渲染请求添加任何新参数。
  • If you’ve tried to get username and password parameters by using render request, you will get null for both of them.如果尝试使用渲染请求获取用户名和密码参数,则这两个参数都将为null。

Context Path: The Portlet’s context path is that part of URL corresponds to the Portlet’s context. Acquiring of context path is very helpful especially when a reference to a web resources is required. You may redirect your request into other web resources like Servlet by adding the context path into resource name.

上下文路径 :Portlet的上下文路径是URL的一部分与Portlet的上下文相对应。 获取上下文路径非常有帮助,尤其是在需要引用Web资源的情况下。 您可以通过将上下文路径添加到资源名称中来将请求重定向到其他Web资源(如Servlet)。

Context path can be specified by using either of action or render requests.

可以使用动作请求或渲染请求来指定上下文路径。

Preferred Locales & Internationalization: It’s also possible for you to query the current locale that will be used for rendering the content. You may invoke the getLocale() or getLocales() for getting the current locale used and the list of locales for which the Portlet could provide the content for the Portal.

首选语言环境和国际化 :您还可以查询将用于呈现内容的当前语言环境。 您可以调用getLocale()getLocales()来获取当前使用的语言环境以及Portlet可以为其提供门户内容的语言环境列表。

Retrieving The Schema, Server Name and Port: Similar for HttpServletRequest, PortletRequest provides you the needed methods for inquiring the schema of the URL used for the request (e.g http, https, ftp, etc), the server’s name and the port number that the application is listening for.

检索模式,服务器名称和端口 :与HttpServletRequest类似, PortletRequest为您提供查询用于请求的URL的模式(例如http,https,ftp等),服务器名称和端口号的必要方法。应用程序正在监听。

Even you’re probably won’t get used these methods as you don’t need to create the needed URLs by yourself. Methods like createActionURL() and createRenderURL() will be used alternatively.

甚至您可能也不会使用这些方法,因为您不需要自己创建所需的URL。 诸如createActionURL()createRenderURL()将被替代使用。

渲染请求 (Render Request)

As we’ve seen previously, render() method takes a RenderRequest as one of the arguments. RenderRequest is used to represent the request for the render phase.

如前所述,render()方法将RenderRequest作为参数之一。 RenderRequest用于表示渲染阶段的请求。

动作请求和文件上传 (Action Request & File Uploading)

At the same time, the request that’s passed for processAction() method is of type ActionRequest and it represents the request for the action phase.

同时,为processAction()方法传递的请求的类型为ActionRequest,它表示操作阶段的请求。

ActionReqeust provides you two different methods that will help you read the content of the request body, getReader() and getPortletInputStream() are used for this purpose. Mainly, if your form posted data its MIME type is application/x-www-form-urlencoded, the Portlet container will read the request body on behalf of you and you will get the form’s data as a request parameters.

ActionReqeust为您提供了两种不同的方法来帮助您读取请求正文的内容,为此目的使用了getReader()和getPortletInputStream()。 主要是,如果您的表单发布数据的MIME类型是application / x-www-form-urlencoded,则Portlet容器将代表您读取请求正文,您将获得表单数据作为请求参数。

As soon as you’ve called a getReader() or getPortletInputStream() while reading the request body from a form’s its MIME type is application/x-www-form-urlencoded, you’ve surly got an IllegalStateException that print out the message says User request HTTP POST data is of type application/x-www-form-urlencoded. This data has been already processed by the portlet-container and is available as request parameters.

从表单的MIME类型为application / x-www-form-urlencoded的表单中读取请求正文时,调用getReader()或getPortletInputStream()时,您肯定会收到一个IllegalStateException,该异常会打印出消息说用户请求HTTP POST数据的类型为application / x-www-form-urlencoded。 此数据已由Portlet容器处理,可以用作请求参数。

You’re able of getting read the form’s data that MIME value is multipart/form-data. But be careful as you can open one reader at the same time. As soon as the getReader() has been used, using of getPortletInputStream() will throw an IllegalStateException and the same case when opposite is happened. Following sample shows you how can we submit two different forms, one of them is aimed to upload the file.

您可以读取MIME值为multipart / form-data的表单数据 。 但是要小心,因为您可以同时打开一个阅读器。 一旦使用了getReader(),使用getPortletInputStream()就会抛出IllegalStateException和发生相反情况的相同情况。 以下示例向您展示了我们如何提交两种不同的表单,其中一种旨在上传文件。

package com.journaldev.portlet;import java.io.IOException;
import java.util.List;import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.portlet.PortletFileUpload;public class ActionRequestReader extends GenericPortlet{public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {response.getWriter().println("<form action="+response.createActionURL()+" method='POST' enctype='application/x-www-form-urlencoded'>"+ "Enter message : <input type='text' id='message' name='message'/>"+ "<input type='submit' value='Submit Form Message'/><br/>"+ "</form>"+ "<form action="+response.createActionURL()+" method='POST' enctype='multipart/form-data'>"+ "Upload Your File: <input type='file' name='fileUpload'/>"+ "<input type='submit' value='Upload File'/>"+ "</form>");}public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {// Handle default MIME type requestif(request.getContentType().equals("application/x-www-form-urlencoded")){String message = request.getParameter("message");System.out.println(message);}// Handle multipart requestelse if(request.getContentType().contains("multipart/form-data")){// Create FileItemFactoryFileItemFactory factory = new DiskFileItemFactory();// Create PortletFileUpload instancePortletFileUpload fileUpload = new PortletFileUpload(factory);try {// Instead of parsing the request ourselves, let Apache PortletFileUpload do thatList<FileItem> files = fileUpload.parseRequest(request);// Iterate over filesfor(FileItem item : files){// Print out some of informationSystem.out.println("File Uploaded Name Is : "+item.getName()+" , Its Size Is :: "+item.getSize());}} catch (FileUploadException e) {e.printStackTrace();}}}
}

Here’s detailed explanation for the code listed above:

这是上面列出的代码的详细说明:

  • GetContentType is used for determining which type of request we’ve handled.GetContentType用于确定我们处理的请求类型。
  • URL-encoded request cannot be read as the Portlet container will do that. So you can find your form’s parameters through using of request.getParameters().无法读取URL编码的请求,因为Portlet容器会这样做。 因此,您可以使用request.getParameters()查找表单的参数。
  • Multipart request can be read using getReader() or getPortletInputstream(). But one can be used per request.可以使用getReader()或getPortletInputstream()读取多部分请求。 但是每个请求可以使用一个。
  • Instead of processing the request manually to get the file uploaded, we used Apache commons upload file library. This library is very smart one as it can handle normal file upload request or Portlet file upload request. See required libraries provided within the pom.xml.我们没有使用手动处理请求来上传文件,而是使用了Apache commons上传文件库。 这个库非常聪明,因为它可以处理正常的文件上传请求或Portlet文件上传请求。 请参阅pom.xml中提供的必需库。
  • Although, we handle the uploaded file using the very trivial way (Just Print out some of file information), but you can use ImageIO api for getting image saved onto your disk space.虽然,我们使用非常简单的方式来处理上传的文件(只需打印出一些文件信息),但是您可以使用ImageIO api将图像保存到磁盘空间中。
  • To get ActionRequestReader Portlet deployed, don’t forget to list it inside portlet.xml file.要部署ActionRequestReader Portlet,请不要忘记在portlet.xml文件中列出它。

Portlet响应 (Portlet Response)

The Portlet sends the response object back to the Portal after every request. The response object contains the Portlet fragment that will be drawn into Portal page. Fragments collective mission is a Portal job.

每个请求之后,Portlet都会将响应对象发送回Portal。 响应对象包含将被绘制到门户页面的Portlet片段。 碎片集体任务是Portal的工作。

PortletResponse provides you a three methods only, setProperty(), getProperty() and encodeURL(). These methods that are relevant for properties will be discussed while introducing the Portlet cache concept. Using of encodeURL() is mandatory for some of Portlet container implementations, in that some resources (e.g Servlet, JSP, etc) within the Portlet application need to be referenced using some additional data like SessionID and may others.

PortletResponse仅为您提供三种方法, setProperty()getProperty()encodeURL() 。 在介绍Portlet高速缓存概念时,将讨论与属性相关的这些方法。 对于某些Portlet容器实现,必须使用encodeURL() ,因为需要使用某些附加数据(如SessionID以及其他一些数据)来引用Portlet应用程序内的某些资源(例如Servlet,JSP等)。

According to Java Portlet Specification, if encoding isn’t needed, the Portlet container will return the URL unchanged.

根据Java Portlet规范,如果不需要编码,则Portlet容器将返回不变的URL。

渲染响应 (Render Response)

Mainly, we’ve used RenderResponse object for writing content fragment into Portal page. RenderResponse object has provided two methods for getting content drawn, getWriter() and getPortletOutputStream() are available for that purpose.

主要是,我们使用RenderResponse对象将内容片段写入Portal页面。 RenderResponse对象提供了两种获取内容绘制的方法,为此目的可使用getWriter()和getPortletOutputStream()。

But as soon as you’ve used getWriter(), you cannot able of using the getPortletOutputStream() and the opposition is valid. In case you’ve used both of them to handle the content draw, you will get an IllegalStateException.

但是,一旦使用了getWriter(),就无法使用getPortletOutputStream(),并且对立有效。 如果您同时使用它们来处理内容绘制,则将收到IllegalStateException。

The major facility has provided by the RenderResponse object is the getNamespace() method that’s used in a JavaScript code for variable naming identification. Following sample shows you two Portlets have referenced the same Portlet class and they’re provided the same JavaScript method. Let’s look at the scenario before getting getNamespace() used.

RenderResponse对象提供的主要功能是getNamespace()方法,该方法在JavaScript代码中用于变量命名标识。 以下示例显示两个Portlet引用了相同的Portlet类,并且为它们提供了相同JavaScript方法。 让我们先看一下使用getNamespace()之前的场景。

package com.journaldev.portlet;import java.io.IOException;import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;public class RenderResponseNamespaceOne extends GenericPortlet{public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {response.getWriter().println("<html>"+ "<head>"+ "<script>"+ "var message = 'Handle Submit, Portlet One';"+ "function handleSubmit(){"+ " alert('Handle Submit, The Portlet Is '+message);"+ "}"+ "</script>"+ "</head>"+ "<form action="+response.createActionURL()+">"+ "  <input type='button' value='Click On Me' onclick='handleSubmit()'/>"+ "</form>"+ "</html>");}public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {System.out.println("Handled Request ..");}
}
package com.journaldev.portlet;import java.io.IOException;import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;public class RenderResponseNamespaceTwo extends GenericPortlet{public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {response.getWriter().println("<html>"+ "<head>"+ "<script>"+ "var message = 'Handle Submit, Portlet Two';"+ "function handleSubmit(){"+ " alert('Handle Submit, The Portlet Is '+message);"+ "}"+ "</script>"+ "</head>"+ "<form action="+response.createActionURL()+">"+ "  <input type='button' value='Click On Me' onclick='handleSubmit()'/>"+ "</form>"+ "</html>");}public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {System.out.println("Handled Request ..");}
}

Here’s detailed explanation for the code listed above:

这是上面列出的代码的详细说明:

  • As the same message variable is defined for both of the Portlet, the last value of message variable will be used.由于为两个Portlet定义了相同的消息变量,因此将使用消息变量的最后一个值。
  • Both of Portlets will use the same message variable and specifically the last one of this variable.两个Portlet都将使用相同的消息变量,尤其是此变量的最后一个。

To get this issue resloved, getNamespace() can be used, following below the solution that you may use as long as your JavaScript code is listed on the Portlet itself.

要解决此问题,只要在Portlet本身上列出了JavaScript代码,就可以在下面的解决方案下面使用getNamespace()。

package com.journaldev.portlet;import java.io.IOException;import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;public class RenderResponseNamespaceOne extends GenericPortlet{public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {response.getWriter().println("<html>"+ "<head>"+ "<script>"+ "var "+response.getNamespace()+"message = 'Handle Submit, Portlet One';"+ "function "+response.getNamespace()+"handleSubmit(){"+ " alert('Handle Submit, The Portlet Is '+"+response.getNamespace()+"message);"+ "}"+ "</script>"+ "</head>"+ "<form action="+response.createActionURL()+">"+ "  <input type='button' value='Click On Me' onclick='"+response.getNamespace()+"handleSubmit()'/>"+ "</form>"+ "</html>");}public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {System.out.println("Handled Request ..");}
}
package com.journaldev.portlet;import java.io.IOException;import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;public class RenderResponseNamespaceTwo extends GenericPortlet{public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {response.getWriter().println("<html>"+ "<head>"+ "<script>"+ "var "+response.getNamespace()+"message = 'Handle Submit, Portlet Two';"+ "function "+response.getNamespace()+"handleSubmit(){"+ " alert('Handle Submit, The Portlet Is '+"+response.getNamespace()+"message);"+ "}"+ "</script>"+ "</head>"+ "<form action="+response.createActionURL()+">"+ "  <input type='button' value='Click On Me' onclick='"+response.getNamespace()+"handleSubmit()'/>"+ "</form>"+ "</html>");}public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {System.out.println("Handled Request ..");}
}

Here’s detailed explanation for the code listed above:

这是上面列出的代码的详细说明:

  • If you’ve used the sample above, you should find two different handleSubmit() method as well as two different message variables that are named Pluto_PortletConcepts_RenderResponseNamespaceOne__1332422274_0_message and Pluto_PortletConcepts_RenderResponseNamespaceTwo__1332422274_1_message respectively.如果使用了上面的示例,则应该找到两个不同的handleSubmit()方法以及两个不同的消息变量,它们分别名为Pluto_PortletConcepts_RenderResponseNamespaceOne__1332422274_0_messagePluto_PortletConcepts_RenderResponseNamespaceTwo__1332422274_1_message
  • This strategy would help as long as the JavaScript code is provided within the Portlet. If you’ve set your JavaScript code inside an external file, this strategy isn’t so helpful.只要在Portlet中提供了JavaScript代码,该策略就将有所帮助。 如果您已将JavaScript代码设置在外部文件中,则此策略不是很有用。

动作回应 (Action Response)

Typically, action response used for two different major missions; for passing the parameters for the render phase through using of setRenderParamater() and for redirect the request into any other resources than let the normal flow proceeds. Redirection has been done using of sendRedirect() as you can redirect into any resources like Servlet or JSP. Both of these behaviors are discussed and we also had provided samples for both of them.

通常,行动响应用于两个不同的主要任务; 通过使用setRenderParamater()传递渲染阶段的参数,以及将请求重定向到其他任何资源(正常流程除外)。 重定向已使用sendRedirect()完成,因为您可以重定向到任何资源,例如Servlet或JSP。 讨论了这两种行为,我们还提供了两种示例。

摘要 (Summary)

Portlet API contains a lot of concepts that we must be aware of. This tutorial has discussed the most APIs that you should be familiar with as they would be helpful in the next coming tutorials. Contribute us by commenting below and find downloaded source code.

Portlet API包含许多我们必须意识到的概念。 本教程讨论了您应该熟悉的大多数API,因为它们将在以后的教程中有所帮助。 通过在下面评论来贡献我们,并找到下载的源代码。

Download Portlet Concepts Project下载Portlet概念项目

翻译自: https://www.journaldev.com/4808/portlet-tutorial

portlet

portlet_Portlet教程相关推荐

  1. 使用Docker搭建svn服务器教程

    使用Docker搭建svn服务器教程 svn简介 SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很 ...

  2. mysql修改校对集_MySQL 教程之校对集问题

    本篇文章主要给大家介绍mysql中的校对集问题,希望对需要的朋友有所帮助! 推荐参考教程:<mysql教程> 校对集问题 校对集,其实就是数据的比较方式. 校对集,共有三种,分别为:_bi ...

  3. mysql备份psb文件怎么打开_Navicat for MySQL 数据备份教程

    原标题:Navicat for MySQL 数据备份教程 一个安全和可靠的服务器与定期运行备份有密切的关系,因为错误有可能随时发生,由攻击.硬件故障.人为错误.电力中断等都会照成数据丢失.备份功能为防 ...

  4. php rabbmq教程_RabbitMQ+PHP 教程一(Hello World)

    介绍 RabbitMQ是一个消息代理器:它接受和转发消息.你可以把它当作一个邮局:当你把邮件放在信箱里时,你可以肯定邮差先生最终会把邮件送到你的收件人那里.在这个比喻中,RabbitMQ就是这里的邮箱 ...

  5. 【置顶】利用 NLP 技术做简单数据可视化分析教程(实战)

    置顶 本人决定将过去一段时间在公司以及日常生活中关于自然语言处理的相关技术积累,将在gitbook做一个简单分享,内容应该会很丰富,希望对你有所帮助,欢迎大家支持. 内容介绍如下 你是否曾经在租房时因 ...

  6. Google Colab 免费GPU服务器使用教程 挂载云端硬盘

    一.前言 二.Google Colab特征 三.开始使用 3.1在谷歌云盘上创建文件夹 3.2创建Colaboratory 3.3创建完成 四.设置GPU运行 五.运行.py文件 5.1安装必要库 5 ...

  7. 理解和实现分布式TensorFlow集群完整教程

    手把手教你搭建分布式集群,进入生产环境的TensorFlow 分布式TensorFlow简介 前一篇<分布式TensorFlow集群local server使用详解>我们介绍了分布式Ten ...

  8. 高级教程: 作出动态决策和 Bi-LSTM CRF 重点

    https://www.zhihu.com/question/35866596 条件随机场 CRF(条件随机场)与Viterbi(维特比)算法原理详解 https://blog.csdn.net/qq ...

  9. PyTorch 高级实战教程:基于 BI-LSTM CRF 实现命名实体识别和中文分词

    20210607 https://blog.csdn.net/u011828281/article/details/81171066 前言:译者实测 PyTorch 代码非常简洁易懂,只需要将中文分词 ...

最新文章

  1. 蓝鸥Unity开发基础二——课时20 接口
  2. LeetCode: Unique Binary Search Trees [095]
  3. DFS 之 poj 2386 Lake Counting
  4. Elasticsearch学习(2)—— 常见术语
  5. android 面试总结,后续注意学习
  6. Springmvc 返回html视图解决
  7. C++中回调函数(CALLBACK)初探
  8. opencv+python 霍夫圆检测原理
  9. 华为手机网络连接不可用怎么解决_和平精英卡顿怎么解决?玩手机游戏用什么加速器比较好?...
  10. 大学数学视频教程整理
  11. 【C++程序设计实践】实验十一
  12. 数据结构(计算机存储、组织数据方式)
  13. 使用 Nginx 搭建多平台直播
  14. H5微信中棋牌游戏域名防封解决方案
  15. js的json php无法json_decode,PHP中遇到BOM、 编码导致json_decode函数无法解析问题
  16. Anaconda - conda 常用命令
  17. 【LinuxUnix--exec 与 fock 系统调用】
  18. python制作二维码_基于Python生成个性二维码过程详解
  19. 美国首例!Autopilot事故致2人死亡 特斯拉车主被控过失杀人
  20. 清华系激光雷达公司,成了量产元年最大的黑马

热门文章

  1. pid 以单摆系统为例
  2. 我也是“抽象派画家”!
  3. 『津津乐道播客』#132. 《流浪地球》带火了中国科幻?
  4. 二进制、八进制、十进制、十六进制之间的互相转换_20200711
  5. [飞腾]Trace32使用概述
  6. 厦门亿联2018面试题
  7. NAND FLASH中plane的概念
  8. JAVA类的继承 Teacher和Student
  9. 问号表达式 a?b:c
  10. 雅可比迭代实验报告c语言,雅可比迭代实验报告.doc