# portlet示例_Java Portlet示例教程

portlet示例

In the presented introduction about Apache Pluto, we’ve mainly discussed the most simple Portlet application that you may have. The business scenarios are more complicated then normal and they require a full knowledge about the Portlet, Portlet Life cycle and how could provide a compliant enhanced Portlet that complying with the latest standards presented at the Portlet field.

## Portlet教程 (Portlet Tutorial)

This tutorial will help you getting this practice applied, while it should take you through the following subjects:

### 有关GenericPortlet的更多信息 (Little Bit More About GenericPortlet)

As we’ve stated in the proposed introduction, our developed Portlet was extended a GenericPortlet class as it’s abstract class. According to Portlet Javadoc, GenericPortlet class provides the default implementation for the Portlet interface (Which will be discussed later on here). It provides an abstract class to be sub-classed to create Portlets.

A subclass of GenericPortlet should either use one of the following annotations: @ProcessAction, @ProcessEvent and @RenderMode or override at least one method of the following:

GenericPortlet的子类应使用以下注释之一： @ProcessAction@ProcessEvent@RenderMode或重写以下至少一种方法：

• processAction: to handle action requests (will be discussed later on in this tutorial).

processAction ：处理动作请求（将在本教程后面讨论）。
• doView: to handle render requests when the Portlet is in the View mode.

doView ：在Portlet处于查看模式时处理渲染请求。
• doEdit: to handle render requests when the Portlet is in the Edit mode.

doEdit ：在Portlet处于“编辑”模式时处理渲染请求。
• doHelp: to handle render requests when the Portlet is in the Help mode.

doHelp ：当Portlet处于帮助模式时，处理渲染请求。
• init and destroy: to manage resources that are held for the life of the Servlet.

initdestroy ：管理在Servlet生命周期内保留的资源。

Normally, no need to override the render or the doDispatch methods, as the render method handles render requests, setting the title of the Portlet in the response and invoking the doDispatch.

In turn of the doDispatch method, the request is dispatched to one of the doView, doEdit or doHelp method depending on the Portlet mode indicated in the request. The major issue that you might find it so important, is that the Portlet is running in a multi threaded manner, so be careful when it comes to handle shared resources. Shared resources may take different forms; it’s include in-memory data such as instance or class variables, external resources like a files, database connections and network connections.

In the proposed sample that you’ve looked for at the introduction, we’ve overridden the doView method for getting message displayed. We do, some modifications against the sample itself, so you should notice the following:

• We’ve eliminated the overriding of doView method, as we used @RenderMode annotation to annotate a new method called inspectRenderMode.

我们已经消除了doView方法的重载，因为我们使用了@ RenderMode批注来注释一个名为inspectRenderMode的新方法。
• We’ve updated the pom.xml file, so no need to get your generated WAR every time and copy it into your Tomcat’s webapp deployment folder. That’s done by using an integration-test phase that asks Ant to make that in behind of you.

我们已经更新了pom.xml文件，因此无需每次获取生成的WAR并将其复制到Tomcat的webapp部署文件夹中。 这是通过使用一个integration-test阶段来完成的，该阶段要求Ant将其放在您的后面。
package com.journaldev.portlet;

import java.io.IOException;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.RenderMode;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class HelloWorldPortlet extends GenericPortlet {
@RenderMode(name="View")
public void inspectRenderMode(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
response.getWriter().print(
"Jounral Dev Provides you Hello World Portlet Using Annotations !");
}

public void init( PortletConfig config ) throws PortletException {
super.init( config );
}
}
<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>HelloWorldPortlet</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>HelloWorldPortlet Maven Webapp</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>
<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> <phase>integration-test</phase> <configuration> <tasks> <!-- Use this to build and deploy the testsuite war. PORTLET_DEPLOY_DIR is an environmental variable pointing to the hot-deploy directory of your portal. You can also use -Ddeploy.dir=<path to deployment dir> on the command line when invoking maven: mvn -Ddeploy.dir=/pluto-1.1.4/webapps integration-test --> <property environment="env" /> <property name="deploy.dir" value="${env.PORTLET_DEPLOY_DIR}" />
<copy file="target/${pom.build.finalName}.war" tofile="${deployFolder}/\${pom.build.finalName}.war" />
</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:

• JSR-286 has introduced the using of annotations for controlling things were controlled normally through overriding GenericPortlet methods. We’ve used @renderMode instead of overriding doView method done like before.

JSR-286引入了使用注释来控制通过覆盖GenericPortlet方法正常控制的事物的方法。 我们使用@renderMode而不是像以前一样重写doView方法。
• We’ve added antrun plugin to replace the old way of deploying that we were used. Now, what’s really you want to do is to execute mvn clean integration-test package to get your WAR copied and deployed directly underneath of your Tomcat’s webapp folder. This procedure will be used henceforward.

我们添加了antrun插件来替代以前使用的旧部署方式。 现在，您真正想要做的是执行mvn clean integration-test package以将WAR复制并直接部署在Tomcat的webapp文件夹下。 此后将使用此过程。

Finally, if you have a special kind of business that you would like to provide such a type of integration, you may make a subclass of GenericPortlet and let your developers extend it.

### 关于PortletRequest和PortletResponse的更多信息 (Little Bit More About PortletRequest & PortletResponse)

The PortletRequest interface in the Portlet API represents the common functionality in an ActionRequest and RenderRequest, where both of them are actually subclass of PortletRequest.

Portlet API中的PortletRequest接口表示ActionRequest和RenderRequest中的通用功能，它们实际上都是PortletRequest的子类。

The PortletRequest provides all needed information about the user’s request (e.g request’s parameters), user’s session, Portal, Portlet application and different information about the Portlet itself.

PortletRequest提供有关用户请求的所有必需信息（例如，请求的参数），用户会话，门户网站，Portlet应用程序以及有关Portlet本身的其他信息。

The Portlet container passes all Portlet request and response objects to the Portlet whenever the Portlet get requested.

In the other side, the Portlet sends a response object back to the Portal after every request. Usually, the response object contains the content fragment of the Portlet, any requested Portlet modes or window states and several other pieces of information that get discussed later.

Actually, the Portlet developers haven’t worked with actual instances of PortletRequest and PortletResponse. However, the developers will work with RenderRequest, ActionRequest, RenderResponse and ActionResponse.

You may be asking about the difference between RenderRequest, RenderResponse and ActionRequest, ActionResponse and why they are categorized like that. Following figure shows you the main differences shortly before getting all detailed clarifications in the next coming sections.

TypeDescriptionWho’s Created It
RenderRequestThe RenderRequest represents the request sent to the Portlet to handle a render.The Portlet container creates a RenderRequest object and passes it as argument to the Portlet’s render() method.
RenderResponseThe RenderResponse defines an object to assist a Portlet in sending a response to the Portal.The Portlet container creates a RenderResponse object and passes it as argument to the Portlet’s render() method.
ActionRequestThe ActionRequest represents the request sent to the Portlet to handle an action.The Portlet container creates an ActionRequest object and passes it as argument to the Portlet’s processAction() method.
ActionResponseThe ActionResponse represents the response for the response to an action request.The Portlet container creates an ActionResponse object and passes it as argument to the Portlet’s processAction() method.

As you’ve noticed in the figure shown, Portlet specification defines two different types of request/response, render’s request/response and action’s request/response are mainly the only objects you may revolve around at each time you got into a Portlet development mission.

Such that distinction is very helpful when it comes to deal with the Portlet business, as a Portlet may be rendered at every time the contained Portal page is refreshed, while the action is getting executed at a certain specific time the user has asked for.  To make clear, following sample shows you the difference in between calling render() and processAction().

package com.journaldev.portlet;

import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class HelloWorldPortlet extends GenericPortlet {
private static int renderCount = 0;
private static int actionCount = 0;

public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {

synchronized(this){
renderCount++;
}

response.getWriter().print("<form action="+response.createActionURL()+">"
+ "<p>Render has executed "+renderCount+"</p>"
+ "<p>Render has executed "+actionCount+"</p>"
+ "<input type='submit'/>"
+ "</form>");
}

public void processAction(ActionRequest actionRequest, ActionResponse actionResponse){
synchronized(this){
actionCount++;
}
}

public void init( PortletConfig config ) throws PortletException {
super.init( config );
}
}

Here’s detailed clarifications for code listed above:

• You may notice that the render counter will be incremented by one at every time you’ve got the Portal page rendered. GenericPortlet render method has delegated the control into doView that’s overrode at the HelloWorldPortlet.

您可能会注意到，每次渲染门户页面时，渲染计数器都会增加一。 GenericPortlet呈现方法已将控件委托给在HelloWorldPortlet覆盖的doView中。
• Action counter won’t be incremented until you’ve clicked on the submit action. GenericPortlet processAction method has delegated the control into processAction method that’s overrode at the HelloWorldPortlet.

在您单击提交动作之前，动作计数器不会增加。 GenericPortlet processAction方法已将控件委托给在HelloWorldPortlet覆盖的processAction方法。
• We’ve implemented both of render and action using the Portlet specification 1.0 as no annotation has been used.

我们已经使用Portlet规范1.0实现了渲染和动作，因为未使用任何注释。
• As being render method had called at every time you’ve got your Portal page refreshed, it’s very clear that’s why render isn’t the proper location to put any business logic you may require. If we’ve assumed that we have a business logic like mail sending putting there, so the mail would be sending at every time the Portal page getting refreshed.

由于每次刷新门户网站页面时都会调用render方法，因此很明显，这就是为什么render不是放置您可能需要的任何业务逻辑的适当位置。 如果我们假设有诸如发送邮件的业务逻辑，那么每次刷新门户网站页面时都会发送邮件。

### 增强Portlet (Enhancing Portlet)

Portlet capabilities aren’t stopped here as we’re going to make some improvements to demonstrate other sides of these capabilities. Usually, the Portlet doesn’t render a plain HTML, it’s contained other resources like JavaScript, images and StyleSheets.

Portlet功能不会在这里停止，因为我们将进行一些改进以展示这些功能的其他方面。 通常，Portlet不会呈现纯HTML，而是包含其他资源，例如JavaScript，图像和StyleSheets。

Also, the view mode isn’t the only mode that you lets the end user contact with, EDIT and HELP modes are also supported by the Portlets. Mainly, you may provide an EDIT mode for a kind of configuration, meanwhile, the HELP mode is a good place to provide a helpful information about the Portlet itself.

Beside that, providing Portlet Title isn’t so complex mission, as you can provide the default value using the portlet-info XML tag, you can also change the Title programmatically.

### 更改Portlet标题 (Change The Portlet Title)

Generally, Portlet specification has introduced the portlet-info XML tag to allow developers specifying these information related to the Portlet’s title, short-title and keywords that may be used for categorization purpose.

You have three different scenarios that can you have to let the Portlet get its title, you may be using the most simplest way; define the title at the portlet.xml file within portlet-info or using a resource bundle for getting internationalization descriptive title or providing the title programmatically. Following example shows you how can you leverage two additional scenarios to make sure the desired title is set as we’ve had the first scenario previously.

package com.journaldev.portlet;

import java.util.Locale;
import java.util.ResourceBundle;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class TitleChangedPortlet extends GenericPortlet{
public void doView(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
response.getWriter().println("My Name Is:"+this.getPortletName());
}

public java.lang.String getTitle(RenderRequest request) {
// Check whether the name of the portlet is programmaticTitleChangePortlet
if(this.getPortletName().equals("ProgrammaticTitleChangePortlet")){
// If it's like that, just get the defined bundle
ResourceBundle bundle = this.getPortletConfig().getResourceBundle(new Locale("en"));
// Retrun the string that's corresponded for anyTitle property
return (String)bundle.getObject("anyTitle");
}
// else return the default, either that's defined in the portlet.xml or that's defined in the bundle
return super.getTitle(request);
}
}
package com.journaldev.portlet;

import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class HelloWorldPortlet extends GenericPortlet {
private static int renderCount = 0;
private static int actionCount = 0;

public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {

synchronized(this){
renderCount++;
}

response.getWriter().print("<form action="+response.createActionURL()+">"
+ "<p>Render has executed "+renderCount+"</p>"
+ "<p>Action has executed "+actionCount+"</p>"
+ "<input type='submit'/>"
+ "</form>");
}

public void processAction(ActionRequest actionRequest, ActionResponse actionResponse){
synchronized(this){
actionCount++;
}
}

public void init( PortletConfig config ) throws PortletException {
super.init( config );
}
}

portlet.xml

portlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<portlet-app xmlns="https://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
https://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">

<portlet>
<portlet-name>HelloWorldPortlet</portlet-name>
<display-name>HelloWorldPortlet Portlet</display-name>

<portlet-class>com.journaldev.portlet.HelloWorldPortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>

<portlet-info>
<title>Title Is Set Using Simplest Way Portlet-Info XML Tag</title>
<short-title>Hello World</short-title>
<keywords>Hello,pluto</keywords>
</portlet-info>

</portlet>

<portlet>
<description>It's a Portlet that's setting title using Resource Bundle</description>
<portlet-name>ResourceBundleTitleChangePortlet</portlet-name>
<display-name>ResourceBundleTitleChangePortlet</display-name>

<portlet-class>com.journaldev.portlet.TitleChangedPortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>

<supported-locale>en</supported-locale>

<resource-bundle>message</resource-bundle>

</portlet>

<portlet>
<description>It's a Portlet that's setting title programmatically</description>
<portlet-name>ProgrammaticTitleChangePortlet</portlet-name>
<display-name>ProgrammaticTitleChangePortlet</display-name>

<portlet-class>com.journaldev.portlet.TitleChangedPortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>

<supported-locale>en</supported-locale>

<resource-bundle>message</resource-bundle>

</portlet>

</portlet-app>

message.properties

message.properties

javax.portlet.title=Title Is Set By Resource Bundle
anyTitle=Title Is Set Programmatically

Here’s detailed explanation for code shown above:

• It’s possible to use the same Portlet with different names. We’ve used TitleChangedPortlet twice; once under ResourceBundleTitleChangePortlet name and second with ProgrammaticTitleChangePortlet.

可以将同一Portlet使用不同的名称。 我们已经两次使用TitleChangedPortlet了； 一次在ResourceBundleTitleChangePortlet名称下，第二次在ProgrammaticTitleChangePortlet
• HelloWorldPortlet uses the title that’s defined within the portlet.xml file.

HelloWorldPortlet使用在portlet.xml文件中定义的标题。
• ResourceBundleTitleChangePortlet uses the title that’s defined inside resource bundle. As you’ve noticed you must use the well-known constants as they must be compliant with Portlet specification to be considered. Following below the constants for the Portlet level resource bundle:

ResourceBundleTitleChangePortlet使用在资源束中定义的标题。 正如您已经注意到的那样，必须使用众所周知的常量，因为它们必须符合Portlet规范才能被考虑。 以下是Portlet级别资源束的常量：
ConstantDescription
javax.portlet.titleThe,title that should be displayed in the titlebar of,this portlet. Only one title per locale is allowed. Note,that this title may be overrided by the portal or,programmatically by the portlet.
javax.portlet.short-titleA short,version of the title that may be used for,devices with limited display,capabilities. Only one,short title per locale is allowed.
javax.portlet.keywordsKeywords,describing the functionality of the portlet.,Portals that allow users to search for portlets based,on keywords may use these keywords. Multiple,keywords per locale are allowed, but must be,separated by commas ‘,’.
javax.portlet.descriptionDescription,of the portlet.
javax.portlet.display-nameName,under which this portlet is displayed at,deployment time or to tools. The display name need,not be unique.
javax.portlet.app.custom-portletmode.<,name>.decoration-nameDecoration,name for the portlet managed custom,portlet mode .

javax.portlet.title 该portlet的标题栏中应显示的标题。 每个语言环境仅允许一个标题。 注意，此标题可能会被门户网站覆盖，或者被portlet编程覆盖。
javax.portlet.short-title 可能用于显示能力有限的设备的标题的简短版本。 每个区域仅允许一个简短的标题。
javax.portlet.keywords 关键字，描述portlet的功能。允许用户基于关键字搜索portlet的portals可以使用这些关键字。 每个区域允许使用多个关键字，但必须用逗号“，”分隔。
javax.portlet.description Portlet的描述。
javax.portlet.display-name 部署时或工具上显示此portlet的名称。 显示名称不必唯一。
javax.portlet.app.custom-portletmode。<，名称>。装饰名称 装饰，portlet管理的定制的名称，portlet模式。
• Typically, you should define your resources within the same package as your Portlet to make sure every Portlet has used its relevant messages.

通常，您应该在与Portlet相同的包中定义资源，以确保每个Portlet都使用了其相关消息。
• ProgrammaticTitleChangePortlet uses the title that’s changed programmatically. Even that we can provide a static text, but we’ve provide another use of bundle messages.

ProgrammaticTitleChangePortlet使用以编程方式更改的标题。 即使我们可以提供静态文本，也可以提供捆绑消息的另一种用法。
• In case you need to provide the title programmatically, you must do override for the getTitle() method that’s already inherited from the GenericPortlet.

如果需要以编程方式提供标题，则必须对已经从GenericPortlet继承的getTitle()方法进行重写。
• If you’re used resource bundle for getting Portlet’s accompanies text defined, you must make sure that you have your resource files (e.g message.properties) located into your class path as you’ve defined it in the portlet.xml.

如果使用资源包来定义Portlet的伴随文本，则必须确保已在portlet.xml定义资源文件（例如message.properties）到类路径中。
• Another way to change the title programmatically, you can invoke setTitle() against renderResponse object inside any delegated method (i.e doView, doEdit and doHelp).

以编程方式更改标题的另一种方法是，您可以在任何委托的方法（即doView，doEdit和doHelp）内针对renderResponse对象调用setTitle() ）。

### Portlet URL (Portlet URLs)

As we knew, the Portlet isn’t a standalone resource like Servlet that can be accessed through a well defined URL (i.e https://servername:port/web-context/servlet-mapping). The Portlet can be accessed only via using a Portal page, as it’s reside there.

However, a Portlet can create a URL that targets itself in the Portlet container (i.e by clicking a link or submitting a form) the result is a new client request to the Portal targeted to the Portlet as we already did when submitting HelloWorldPortlet above.

Anyway, these URL’s are called portlet URLs. In that, a Portlet URL will reference the instance of the portlet in the Portal page (In case you have two different Portlets referenced the same Portlet class, they will have different Portlet URLs).

Creation of these URLs is a Portlet container responsibility as it’s also parsed the Portlet URL into parameters for the Portlet request. The Portlet creates PortletURL objects that represent Portlet URLs. The Portlet itself can use one of two methods on the RenderResponse class to create these PortletURL objects:

• createActionURL(): Is used to make action URLs for HTML forms or links. These actions URLs are useful for processing actions (i.e Portlet’s state modifications) on the Portlet (i.e calling of processAction() overrode method against your Portlet).

createActionURL() ：用于为HTML表单或链接创建操作URL。 这些操作URL对于处理Portlet上的操作（即，对Portlet调用processAction()覆盖方法processAction()非常有用。
• createRenderURL(): Is used to make render URLs for any tasks that doesn’t contain Portlet’s state modifications.

createRenderURL() ：用于为不包含Portlet状态修改的任何任务创建渲染URL。

Even that you can add Portlet URLs into your content with no parameters, but you can also set your parameters on a Portlet URLs by invoking setParameter(name, value) against your PortletURL object that’s returned once you invoked createActionURL() or createRenderURL().

More clarifications and samples would be delivered in the next coming tutorial that’s aimed to cover all technical specifics for accompanies render’s request/response and action’s request/response and how’s the parameter can be set and consumed after then.

### doEdit和doHelp方法 (doEdit & doHelp Methods)

Practically, we’ve not used doEdit method for any type of normal rendition, it’s mainly used for specifying the Portlet’s states for controlling Portlte’s behavior at normal rendition invocation that’s done using doView.

At the same time, some Portlets have provided so complicated business, the user may need some sort of help to get the Portlet working properly and for that purpose the doHelp is given.

Defining the Portlet’s modes isn’t so complex mission, all what you need for is to use portlet-mode within supports Tag for specifying which modes the Portlet has supported. Following example shows you the way that in which you are able of seeing Edit & Help modes.

package com.journaldev.portlet;

import java.util.Locale;
import java.util.ResourceBundle;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class TitleChangedPortlet extends GenericPortlet{

public void doView(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
response.getWriter().println("My Name Is:"+this.getPortletName());
}

public void doEdit(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
response.getWriter().println("Edit Mode On Portlet Name :"+this.getPortletName());
}

public void doHelp(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
response.getWriter().println("Help Mode On Portlet Name :"+this.getPortletName());
}

public java.lang.String getTitle(RenderRequest request) {
// Check whether the name of the portlet is programmaticTitleChangePortlet
if(this.getPortletName().equals("ProgrammaticTitleChangePortlet")){
// If it's like that, just get the defined bundle
ResourceBundle bundle = this.getPortletConfig().getResourceBundle(new Locale("en"));
// Retrun the string that's corresponded for anyTitle property
return (String)bundle.getObject("anyTitle");
}
// else return the default, either that's defined in the portlet.xml or that's defined in the bundle
return super.getTitle(request);
}
}

portlet.xml

portlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<portlet-app xmlns="https://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
https://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">

<portlet>
<portlet-name>HelloWorldPortlet</portlet-name>
<display-name>HelloWorldPortlet Portlet</display-name>

<portlet-class>com.journaldev.portlet.HelloWorldPortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>

<portlet-info>
<title>Title Is Set Using Simplest Way Portlet-Info XML Tag</title>
<short-title>Hello World</short-title>
<keywords>Hello,pluto</keywords>
</portlet-info>

</portlet>

<portlet>
<description>It's a Portlet that's setting title using Resource Bundle</description>
<portlet-name>ResourceBundleTitleChangePortlet</portlet-name>
<display-name>ResourceBundleTitleChangePortlet</display-name>

<portlet-class>com.journaldev.portlet.TitleChangedPortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-mode>EDIT</portlet-mode>
<portlet-mode>HELP</portlet-mode>
</supports>

<supported-locale>en</supported-locale>

<resource-bundle>message</resource-bundle>

</portlet>

<portlet>
<description>It's a Portlet that's setting title programmatically</description>
<portlet-name>ProgrammaticTitleChangePortlet</portlet-name>
<display-name>ProgrammaticTitleChangePortlet</display-name>

<portlet-class>com.journaldev.portlet.TitleChangedPortlet</portlet-class>

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-mode>EDIT</portlet-mode>
<portlet-mode>HELP</portlet-mode>
</supports>

<supported-locale>en</supported-locale>

<resource-bundle>message</resource-bundle>

</portlet>

</portlet-app>

Here’s detailed explanation for code listed above:

• You must define the modes that you want to make your Portlet support for.

您必须定义支持Portlet的方式。
• HelloWorldPortlet does support View mode as it’s Portlet with no Edit or Help.

HelloWorldPortlet确实支持查看模式，因为它是Portlet，没有“编辑”或“帮助”。
• Other two Portlets have defined all of modes are available.

另外两个Portlet定义了所有可用模式。
• Portal provides you the mode user interface for toggling between modes that are supported by the Portlet.

Portal提供了模式用户界面，用于在Portlet支持的模式之间切换。

### 摘要 (Summary)

Portlet specification provide vast amount of APIs that you have to learn to be Portlet developer. This tutorial aimed to provide you additional details about GenericPortlet, PortletRequest, PortletResponse and others. Contribute us by commenting below and find downloaded source code.

Portlet规范提供了成为Portlet开发人员必须学习的大量API。 本教程旨在为您提供有关GenericPortlet，PortletRequest，PortletResponse等的更多详细信息。 通过在下面评论来贡献我们，并找到下载的源代码。

portlet示例

• 0
点赞
• 0
评论
• 0
收藏
• 扫一扫，分享海报

11-21 1万+
12-06

02-14 143
12-05 1782
04-25
01-19 2120
11-16 89
02-06
10-12
08-28
12-24
07-18