adalm pluto
In earlier tutorials, we’ve developed different types of Portlet. Portlets are developed using of JSP & Servlet at once and then we learned using of JSF with Portlets. This time we’re going to develop a Portlet using another famous framework like Apache Struts.
在较早的教程中,我们开发了不同类型的Portlet。 Portlet是同时使用JSP和Servlet开发的 ,然后我们学习了JSF与Portlet的结合使用 。 这次,我们将使用另一个著名的框架(例如Apache Struts)来开发Portlet。
Srtuts framework is an MVC-based one, we’ve already covered a lot of topics onto Apache Struts as you can refer for all of them, but this is the first time you will get a Struts application deployed into a Portlet container like Apache Pluto.
Srtuts框架是基于MVC的框架 ,我们已经在Apache Struts上介绍了很多主题,您可以参考所有这些主题,但这是您第一次将Struts应用程序部署到Apache Pluto之类的Portlet容器中。
You’re likely going to use Apache Struts Bridge that is already maintained by Apache itself. However, the same application that you’ve implemented before (Employee Registration Form) will be used in this tutorial but with Struts2 framework.
您可能会使用Apache本身已经维护的Apache Struts Bridge 。 但是,本教程中将使用您之前实现的相同应用程序(员工注册表格),但使用Struts2框架。
The main goal of this application is to help you know all the details required for getting the application deployed and running properly onto any JSR-168/JSR-286 compliant Portlet container.
该应用程序的主要目的是帮助您了解将应用程序部署并正确运行到任何符合JSR-168 / JSR-286的Portlet容器上所需的所有详细信息。
This section would clarify you what the Employee Table is and what are these columns used.
本节将向您阐明什么是“雇员表”以及使用了哪些列。
Employee.sql
Employee.sql
CREATE TABLE `employee` (
`EMP_ID` int(11) NOT NULL AUTO_INCREMENT,
`EMP_NAME` varchar(45) DEFAULT NULL,
`EMP_JOB` varchar(45) DEFAULT NULL,
`EMP_SALARY` int(11) DEFAULT NULL,
PRIMARY KEY (`EMP_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Let’s see the Employee
entity (Model) that would be used for holding the data that are going back and forth between the application and the database store.
让我们看一下Employee
实体(模型),该实体将用于保存在应用程序和数据库存储之间来回传递的数据。
package com.journaldev.data;
public class Employee {
private String id;
private String name;
private String job;
private String salary;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
You may save your time instead of getting delve into creating the project by yourself, by using an Apache Struts Archetype. Following steps will help you creating a Struts Portlet application easily.
通过使用Apache Struts Archetype ,您可以节省时间,而不用自己去创建项目。 以下步骤将帮助您轻松创建Struts Portlet应用程序。
The Maven dependency file has got modified to serve two wanted features:
Maven依赖项文件已修改为提供两个所需功能:
pom.xml
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>EmployeeRegistration-StrutsBridge</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>EmployeeRegistration-StrutsBridge</name>
<properties>
<struts2.version>2.3.16.3</struts2.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<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>
<!-- Apache Struts & Core -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-config-browser-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-portlet-plugin</artifactId>
<version>2.3.16.3</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-junit-plugin</artifactId>
<version>${struts2.version}</version>
<scope>test</scope>
</dependency>
<!-- Commons logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- Apache Struts Portlet Bridge -->
<dependency>
<groupId>org.apache.portals.bridges</groupId>
<artifactId>portals-bridges-struts-1.2.7</artifactId>
<version>1.0.4</version>
</dependency>
<!-- MySQL driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</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}/${project.artifactId}.war" />
<delete dir="${deployFolder}/${project.artifactId}" />
</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>
As you may know, Apache Struts has considered JSP as a view technology, so we would add a three distinct files, register.jsp
, success.jsp
and failure.jsp
.
您可能知道,Apache Struts将JSP视为一种视图技术,因此我们将添加三个不同的文件, register.jsp
, success.jsp
和failure.jsp
。
According for Apache Struts Archetype, the files would be added under WEB-INF/jsp/employee folder.
对于Apache Struts Archetype,文件将添加到WEB-INF / jsp / employee文件夹下。
register.jsp
register.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Register Employee</title>
</head>
<body>
<s:form action="register">
<s:textfield name="id" label="Identifier"></s:textfield>
<s:textfield name="name" label="Name"></s:textfield>
<s:textfield name="job" label="Job"></s:textfield>
<s:textfield name="salary" label="Salary"></s:textfield>
<s:submit value="Register"></s:submit>
</s:form>
</body>
</html>
failure.jsp
failure.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Failure</title>
</head>
<body>
<span style="color:red">Unfortunately! The Employee hasn't been registered successfully</span>
</br>
<a href="<s:url action="index" portletMode="view"/>">Try Again!</a>
</body>
</html>
success.jsp
success.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Success</title>
</head>
<body>
<span style="color:green">Congratulations! The Employee has been registered successfully</span>
<br/>
<a href="<s:url action="index" portletMode="view"/>">Register Another</a>
</body>
</html>
As you’ve noticed, we used a Struts Tag library for providing a form component and its relevant parameters. If you’re not so good with a Struts, it’s so good for you return here to read some articles about it as it’s very elegant framework.
您已经注意到,我们使用了Struts Tag库来提供表单组件及其相关参数。 如果您对Struts不太满意,那么回到这里阅读一些有关它的文章就非常好,因为它是一个非常优雅的框架。
Struts Tag library has provided a <url/> Tag for creating a Struts-based link. Struts-based link is a link that uses the Struts framework vocabulary like action.
Struts标记库提供了一个<url />标记,用于创建基于Struts的链接。 基于Struts的链接是使用Struts框架词汇之类的动作的链接。
One important thing you should notice that and it’s the action attribute for the form that’s referred for action it’s name is register. That name would be provided by the struts.xml
file that would be discussed later on.
您应该注意的一件重要事情是,为动作引用的表单的动作属性是注册。 该名称将由struts.xml
文件提供,稍后将进行讨论。
It’s may be known for you that a Struts is an action-based framework. In that, every form submission should be delegated into action based class that’s implemented to be extended from DefaultActionSupport
class. Following RegisterAction
Struts action class.
您可能已经知道Struts是基于动作的框架 。 这样,每个表单提交都应该委托给基于动作的类,该类已实现为从DefaultActionSupport
类扩展。 跟随RegisterAction
Struts动作类。
package com.journaldev.action;
import java.io.IOException;
import java.sql.SQLException;
import javax.portlet.PortletPreferences;
import org.apache.log4j.Logger;
import org.apache.struts2.dispatcher.DefaultActionSupport;
import org.apache.struts2.portlet.interceptor.PortletPreferencesAware;
import com.journaldev.dao.EmployeeDAO;
import com.journaldev.data.Employee;
public class RegisterAction extends DefaultActionSupport implements PortletPreferencesAware {
private static Logger logger = Logger.getLogger(RegisterAction.class);
private static final long serialVersionUID = 1L;
private PortletPreferences preferences;
private String id;
private String name;
private String job;
private String salary;
public PortletPreferences getPreferences() {
return preferences;
}
public void setPreferences(PortletPreferences preferences) {
this.preferences = preferences;
}
@Override
public void setPortletPreferences(PortletPreferences prefs) {
this.preferences = prefs;
}
@Override
public String execute() throws Exception {
try {
Employee employee = new Employee();
employee.setId(id);
employee.setName(name);
employee.setJob(job);
employee.setSalary(salary);
// Register Employee
employee = EmployeeDAO.getInstance().createEmployee(employee);
logger.debug("Employee Has Registered");
return "SUCCESS";
} catch (IllegalAccessException | ClassNotFoundException | SQLException | IOException e) {
logger.debug("Registration Process Has Failed",e);
return "FAILURE";
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
}
Here’s detailed explanation for the RegisterAction
class figured out:
这里是对RegisterAction
类的详细说明:
register.jsp
page. 请注意,类的属性id,名称,工作和薪水与register.jsp
页面提供的这些参数的名称相似。 RegisterAction
has overridden an execute
method for serving the employee registration purposes. RegisterAction
已覆盖用于服务员工注册目的的execute
方法。 Struts.xml file is an XML-based file that used by the Apache Struts framework for getting connected the different components that you’re developed.
Struts.xml文件是基于XML的文件,Apache Struts框架使用该文件来连接所开发的不同组件。
Wiring of mentioned actions within your <s:form/> with the Struts-action must be defined as an entries within struts.xml
file. Following Struts configuration file required:
必须将<s:form />中提到的动作与Struts-action的连线定义为struts.xml
文件中的一项。 需要以下Struts配置文件:
struts.xml
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"https://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="default" extends="struts-portlet-default"
namespace="/employee">
<action name="index">
<result>/WEB-INF/jsp/employee/register.jsp</result>
</action>
</package>
<package name="employee" namespace="/employee" extends="struts-portlet-default">
<action name="register" class="com.journaldev.action.RegisterAction">
<result name="SUCCESS">/WEB-INF/jsp/employee/success.jsp</result>
<result name="FAILURE">/WEB-INF/jsp/employee/failure.jsp</result>
</action>
</package>
</struts>
Integration of Apache Struts with the given Portlet container has been done through using of portlet.xml file. In that, a new init-param should be used for this purpose. Following the Portlet.xml file that’s used.
通过使用portlet.xml文件,已将Apache Struts与给定的Portlet容器集成在一起。 因此,应为此目的使用新的init参数。 在使用的Portlet.xml文件之后。
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
https://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<description>Register Employee</description>
<portlet-name>RegisterEmployee</portlet-name>
<portlet-class>org.apache.struts2.portlet.dispatcher.Jsr286Dispatcher</portlet-class>
<init-param>
<name>actionPackages</name>
<value>com.journaldev.action</value>
</init-param>
<!-- The namespace for the actions configured for view mode -->
<init-param>
<name>viewNamespace</name>
<value>/employee</value>
</init-param>
<!-- The default action to invoke in view mode. -->
<init-param>
<name>defaultViewAction</name>
<value>index</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<portlet-info>
<title>Register Employee</title>
<short-title>Register Employee</short-title>
<keywords>Employee,Registration</keywords>
</portlet-info>
</portlet>
</portlet-app>
Here’s detailed explanation for both of the Struts and Portlet configuration files listed above:
这是上面列出的Struts和Portlet配置文件的详细说明:
JSR286Dispatcher
class. 您的Portlet必须是JSR286Dispatcher
类的实例。 defaultViewAction
will be used once you’ve opened the Portal page that’s contained the deployed Portlet. As being index is the value, the index should be defined as an action in the struts.xml file. 打开包含已部署Portlet的Portal页面后,将使用已定义的defaultViewAction
。 由于索引是值,因此应该将索引定义为struts.xml文件中的操作。 actionPackages
will be used for determining the Java package that contains the Struts-actions classes. 定义的actionPackages
将用于确定包含Struts-actions类的Java包。 viewNamespace
will determine the namespace for the actions configured for view mode
. It’s also applicable to define actions for edit
and help
modes. 定义的viewNamespace
将确定为view mode
配置的动作的名称空间。 它也适用于定义edit
和help
模式的动作。 register
action that would be used as soon as the user has submitted the form’s register. Struts配置文件已定义一个register
动作,用户提交表单的注册后将立即使用该动作。 register
action has had two different results, success and failure are used to determine the next view that Struts framework uses after finishing the calling of execute against action class. 定义的register
动作具有两个不同的结果,成功和失败用于确定在完成针对动作类的execute调用之后Struts框架使用的下一个视图。 web.xml
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "https://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>RegisterEmployee</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Following below both of EmployeeDAO and ConnectionUtility that help you getting database connection and creating the user after then.
在EmployeeDAO和ConnectionUtility之下,可以帮助您获得数据库连接并在此之后创建用户。
package com.journaldev.dao;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.journaldev.dao.utility.ConnectionUtility;
import com.journaldev.data.Employee;
public class EmployeeDAO {
public static EmployeeDAO employeeDAO = null;
private EmployeeDAO(){
}
public static EmployeeDAO getInstance(){
synchronized(EmployeeDAO.class){
if(employeeDAO == null){
employeeDAO = new EmployeeDAO();
}
}
return employeeDAO;
}
public Employee createEmployee(Employee employee) throws SQLException, IllegalAccessException, IOException, ClassNotFoundException{
// Get connection instance
Connection connection = ConnectionUtility.getInstance().getConnection();
// Create Prepared Statement
PreparedStatement query = connection.prepareStatement("INSERT INTO EMPLOYEE VALUES (?,?,?,?)");
// Set variables
query.setInt(1, Integer.parseInt(employee.getId()));
query.setString(2, employee.getName());
query.setString(3, employee.getJob());
query.setInt(4, Integer.parseInt(employee.getSalary()));
try {
// Execute
query.execute();
// Return employee instance
return employee;
}
catch(Exception e){
// Close statement
query.close();
// Close connection
connection.close();
// Throw another exception for notifying the Servlet
throw new SQLException(e);
}
}
public boolean deleteEmployee(Employee employee){
return false;
}
public boolean updateEmployee(Employee employee, int employeeId){
return false;
}
}
package com.journaldev.dao.utility;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class ConnectionUtility {
private static ConnectionUtility connectionUtiliy = null;
private Connection connection = null;
private ConnectionUtility() {
}
public static ConnectionUtility getInstance() throws IOException, IllegalAccessException, SQLException, ClassNotFoundException{
// Synchronized against connectionUtility instance
synchronized(ConnectionUtility.class){
// Check whether the connectionUtility is null or not
if(connectionUtiliy == null){
// Create a properties instance
Properties properties = new Properties();
// Load properties from classpath
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("connection.properties"));
// Set connection with connectionUtility
connectionUtiliy = new ConnectionUtility();
// Load driver class
Class.forName("com.mysql.jdbc.Driver");
// Create connection
connectionUtiliy.setConnection(DriverManager.getConnection("jdbc:mysql://localhost:3306/journaldev", properties));
}
return connectionUtiliy;
}
}
public Connection getConnection() throws ClassNotFoundException, SQLException, IOException {
if(connection.isClosed()){
// Create a properties instance
Properties properties = new Properties();
// Load properties from classpath
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("connection.properties"));
// Load driver class
Class.forName("com.mysql.jdbc.Driver");
// Create connection
connectionUtiliy.setConnection(DriverManager.getConnection("jdbc:mysql://localhost:3306/journaldev", properties));
}
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
}
To get started showing your Portlet, you must logged into your Apache Pluto and navigating into JournalDev page. Typically, we have added a Portal page that’s contained for our developed Portlet. The process of creating a Portal page and add the Portlets upon it is discussed at Apache Pluto Introduction Tutorial.
要开始显示Portlet,您必须登录Apache Pluto并导航到JournalDev页面。 通常,我们为开发的Portlet添加了一个Portal页面。 Apache Pluto入门教程讨论了创建Portal页面并在其上添加Portlet的过程。
Apache Struts is an elegant framework that’s used for creating an MVC-based enterprise application. Apache has also provided you a ready made Portlet bridge that could be used for creating JSR-168/286 Struts-based Portlet. Contribute us by commenting below and find the downloaded source code.
Apache Struts是一个优雅的框架,用于创建基于MVC的企业应用程序。 Apache还为您提供了现成的Portlet桥,可用于创建基于JSR-168 / 286基于Struts的Portlet。 通过在下面评论来贡献我们,并找到下载的源代码。
翻译自: https://www.journaldev.com/5035/apache-pluto-portlet-struts-2-integration-example-tutorial
adalm pluto