Apache Pluto和Groovy集成教程示例

时间:2020-02-23 14:29:40  来源:igfitidea点击:

Apache Pluto为您提供了大量集成类型,可用于处理Portlet开发任务。
我们之前已经向您介绍了不同类型的Portlet;标准Portlet(JSR286),JSP和Servlet,JSF 2.0,Struts 2.0,PHP 5,现在是Groovy类型的Portlet。

Groovy是一种Java虚拟语言(JVM),可以像您编写的任何Java类一样在JVM中无缝运行。
Apache Pluto为您提供了Groovy桥,使您可以将Groovy Portlet暴露到门户页面中,而无需其他外观。

本教程旨在为您提供完整的员工注册示例,其中将显示初始页面以收集员工的信息。
用户提交表单后,将开始员工注册,并且还将显示确认消息。

项目结构

下图可以帮助您识别放置Groovy类的最佳位置之一,并为您显示该项目的不同随附文件。

员工表

由于我们拥有注册员工表格,因此让我们看一下"员工表格"的表格及其相关列。

同样,您可以使用下面的SQL create语句将Employee Table创建到Schema中。

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;

员工模式

在MVC设计模式中,并根据关注分离的概念,我们必须具有以下形式的Employee模型:

Employee.java

package com.theitroad.data;

public class Employee {
	private int id;
	private String name;
	private String job;
	private int salary;

	public int getId() {
		return id;
	}

	public void setId(int 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 int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}
}

该模型将保存应用程序中定义的不同组件之间来回的数据。

将Groovy插件安装到Eclipse中

为了确保可以在Maven项目中获取Groovy源码,必须将Eclipse Groovy插件安装到Eclipse IDE中。

安装Eclipse插件不会花费很多时间,因为您可以使用Eclipse安装新软件工具来完成安装。

  • 从帮助菜单中选择安装新软件。

  • 将复制的链接粘贴到"使用输入"中,然后等待Eclipse向您显示插件包含的列出的假定更新。

  • 选择Groovy-Eclipse(必需)并单击下一步。

  • 继续进行操作,直到您的Eclipse安装了Groovy插件,然后重新启动Eclipse以确保已安装的插件生效。

  • 现在,从您之前创建的Maven项目中,正常创建一个Groovy类。

RegisterEmployeePortlet Groovy Portlet

RegisterEmployeePortlet的构建将采用与我们介绍的JSP&Servlet示例相同的方式进行。
它与现在的Groovy类的主要区别在于,该类不需要包声明或者变量类型。

您可以编写类似于您在RegisterEmployeePortlet Java类中编写的代码的代码,但是为了区别起见,我们删除了Groovy不需要的那些可选结构。

RegisterEmployeePortlet.groovy

import java.io.IOException;

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

public class RegisterEmployeePortlet extends GenericPortlet{

	public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
		if(request.getParameter("status") == null){
			//Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/registerEmployee.jsp");
			dispatcher.include(request, response);
		}
		else if(request.getParameter("status") != null &&  request.getParameter("status").equals("initiate")){
			//Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/registerEmployee.jsp");
			dispatcher.include(request, response);
		}
		else if(request.getParameter("status") != null &&  request.getParameter("status").equals("success")){
			//Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/success.jsp");
			dispatcher.include(request, response);
		}
		else if(request.getParameter("status") != null &&  request.getParameter("status").equals("failed")){
			//Create a dispatcher
			def dispatcher =  this.getPortletContext().getRequestDispatcher("/register/failure.jsp");
			request.setAttribute("exception", request.getParameter("exception"));
			dispatcher.include(request, response);
		}		

	}

	public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException{
		//Create request dispatcher
		def dispatcher =  this.getPortletContext().getNamedDispatcher("RegisterEmployeeServlet");
		try {
			//Include
			dispatcher.include(request, response);
			//Set render parameter
			response.setRenderParameter("status", "success");
		}
		catch(Exception ex){
			//Set render parameter
			response.setRenderParameter("status", "failed");
			response.setRenderParameter("exception", ex.getMessage());
		}

	}
}

以下是上述代码的详细说明:

  • RegisterEmployeePortlet Groovy类未引用程序包,因为它包含在上述项目结构的资源中。

  • Groovy是一种动态语言,因此,它适用于您错过变量类型。
    或者,您必须使用一个def关键字,Groovy引擎会从上下文中期望变量的类型。

  • Groovy类还能够访问应用程序内部的任何已定义Servlet。

RegisterEmployeePortlet Groovy Portlet描述符

因为您已经使用Groovy类创建要由Apache Pluto使用的Portlet,所以您知道必须在Portlet部署描述符(Portlet.xml)中提及该Portlet。

Portlet描述符中的Groovy Portlet的定义稍有不同,因为它也包含了您必须了解的其他细节。
首先让我们看一下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 id="RegisterEmployee">
		<display-name>Register Employee</display-name>
		<portlet-name>RegisterEmployee</portlet-name>
		<portlet-class>org.apache.portals.bridges.groovy.GroovyPortlet</portlet-class>
		<init-param>
			<name>script-source</name>
			<value>classpath:RegisterEmployeePortlet.groovy</value>
		</init-param>
		<init-param>
			<name>auto-refresh</name>
			<value>true</value>
		</init-param>
		<description>Employee Registration</description>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>VIEW</portlet-mode>
		</supports>
		<portlet-info>
			<title>Employee Registration</title>
			<keywords>employee, registration</keywords>
			<short-title>Employee Registration</short-title>
		</portlet-info>
	</portlet>
</portlet-app>

以下是上述代码的详细说明:

  • 您的Groovy Portlet应该属于org.apache.portals.bridge.groovy.GroovyPortlet类。

  • 您必须提供script-source,以后将用于指定负责处理启动的Portlet请求的Groovy类。

  • 您可以提供一个可选的自动刷新参数来立即应用您的修改。
    因此,只需进行修改并刷新Portlet即可直接执行它。

  • 脚本源参数接受不同类型的路径。
    完整的物理文件,url,uri或者使用所示的保留关键字classpath。

应用程序部署描述符和Maven构建文件

Web部署描述符没有任何变化,使用的文件与" JSP&Servlet教程"中定义的文件相同。

web.xml

<!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>Employee Registration</display-name>
<servlet>
	<servlet-class>com.theitroad.servlet.RegisterEmployeeServlet</servlet-class>
	<servlet-name>RegisterEmployeeServlet</servlet-name>
</servlet>
<servlet-mapping>
	<servlet-name>RegisterEmployeeServlet</servlet-name>
	<url-pattern>/registerEmployeeServlet</url-pattern>
</servlet-mapping>
<taglib>
	<taglib-uri>https://java.sun.com/portlet</taglib-uri>
	<taglib-location>/WEB-INF/portlet.com</taglib-location>
</taglib>
</web-app>

只需注意,Apache Pluto组装插件将在构建使Portlet可访问的应用程序时向您的web.xml中添加一些片段。

另一方面,所有必需的依赖项都由Maven构建文件维护,请在下面查看所使用的pom.xml。

pom.xml

<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.theitroad</groupId>
	<artifactId>GroovyBridge</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>GroovyBridge</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>
		<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>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<dependency>
			<groupId>org.apache.pluto</groupId>
			<artifactId>pluto-taglib</artifactId>
			<version>1.1.7</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.32</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.groovy</groupId>
			<artifactId>groovy</artifactId>
			<version>1.1-rc-2</version>
		</dependency>
		<dependency>
			<groupId>antlr</groupId>
			<artifactId>antlr</artifactId>
			<version>2.7.6</version>
		</dependency>
		<dependency>
			<groupId>asm</groupId>
			<artifactId>asm</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.portals.bridges</groupId>
			<artifactId>portals-bridges-groovy</artifactId>
			<version>1.0.4</version>
			<exclusions>
				<exclusion>
					<groupId>org.apache.portals.jetspeed-2</groupId>
					<artifactId>jetspeed-api</artifactId>
				</exclusion>
			</exclusions>
		</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.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

EmployeeDAO和ConnectionUtility –数据库处理

EmployeeDAO.java

package com.theitroad.dao;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.theitroad.dao.utility.ConnectionUtility;
import com.theitroad.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, employee.getId());
		query.setString(2, employee.getName());
		query.setString(3, employee.getJob());
		query.setInt(4, 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;
	}
}

ConnectionUtility.java

package com.theitroad.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/theitroad", 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/theitroad", properties));
		}
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

}

RegisterEmployeeServlet –业务处理

相反,如果您注意到Groovy类没有提供与注册过程相关的任何代码,则它主要用于处理所需的业务委托,并且在我们的RegisterEmployeeServlet内部定义了员工注册的实际工作,该概念适用关注分离(Soc)。
看下面:

RegisterEmployeeServlet.java

package com.theitroad.servlet;

import java.io.IOException;

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

import org.apache.log4j.Logger;

import com.theitroad.dao.EmployeeDAO;
import com.theitroad.data.Employee;

public class RegisterEmployeeServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	Logger logger = Logger.getLogger(RegisterEmployeeServlet.class);

  public RegisterEmployeeServlet() {
      super();
  }

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//Create employee
		Employee employee = new Employee();
		//Fill in required data from the request sent
		employee.setId(Integer.parseInt(request.getParameter("employeeID")));
		employee.setName(request.getParameter("employeeName"));
		employee.setJob(request.getParameter("employeeJob"));
		employee.setSalary(Integer.parseInt(request.getParameter("employeeSalary")));
		try {
			//Asking employeeDAO creating the employee against registered database
			Employee createdEmployee = EmployeeDAO.getInstance().createEmployee(employee);
			//Print out the created employee information
			logger.info("Employee Created"+createdEmployee);
		} catch (Exception e) {
			//Log the exception
			logger.error("Employee Creation Failed", e);
			//Throw another exception for notifying the Portlet
			throw new ServletException(e);
		}
	}

}

JSP视图

如上所述,您的Groovy Portlet已将控件委派给三个不同的JSP页面:

registerEmployee.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri='https://java.sun.com/portlet' prefix='portlet'%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Register Employee</title>
</head>
<body>
	<portlet:actionURL var="registerLink"
	<form action="<%=registerLink%>" method="POST">
		<table width="100%">
			<tr width="60%">
				<td>Enter Employee ID:</td>
				<td><input name="employeeID" </td>
			</tr>		
			<tr width="60%">
				<td>Enter Employee Name:</td>
				<td><input name="employeeName" </td>
			</tr>
			<tr width="60%">
				<td>Enter Employee Job:</td>
				<td><input name="employeeJob" </td>
			</tr>
			<tr width="60%">
				<td>Enter Employee Salary:</td>
				<td><input name="employeeSalary" </td>
			</tr>
			<tr width="60%" align="center">
				<td colspan="2"><input type="submit" value="Register" </td>
			</tr>
		</table>
	</form>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri='https://java.sun.com/portlet' prefix='portlet'%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Register Employee</title>
</head>
	<portlet:renderURL var="registerAnother">
		<portlet:param name="status" value="initiate"
	</portlet:renderURL>
	<img src="<%=request.getContextPath()%>/images/success.jpg" name="<portlet:namespaceSuccess"
	<body>
		Congratulations ! you've just add a new employee<br<a href="<%=registerAnother%>">Register Another</a>
	</body>
</html>

failure.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri='https://java.sun.com/portlet' prefix='portlet'%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Register Employee</title>
</head>
	<portlet:defineObjects
	<portlet:renderURL var="registerAnother">
		<portlet:param name="status" value="initiate"
	</portlet:renderURL>
	<body>
		Unfortunately ! you Jan not be able of registering a new employee cause the reason below
		<br
		<br
		<img src="<%=request.getContextPath()%>/images/failed.jpg" name="<portlet:namespaceFailed"
		<span style="font-size:small ;font-style: italic;color: red;font-weight: bold;">
			<%=renderRequest.getAttribute("exception")%>
		
		<br
		<br
		<a href="<%=registerAnother%>">Try Again</a>
	</body>
</html>

员工注册演示

在开始演示员工注册示例之前,您必须已安装Apache Pluto实例以及theitroad门户页面。
如果您以前没有创建过它,则需要返回到Apache Pluto简介以完成所有操作。

而且您应该能够看到新的Employee已保存到数据库中:

而且,如果您尝试使用相同的ID来注册用户,则应该能够看到一条消息,告诉您实际的错误原因。

总结

Groovy是一种动态JVM语言,它令人惊叹,因为您无需了解很多事情,而在使用Java语言时则必须知道这些事情。
如果希望Portlet为您提供最大的动态范围,请选择Groovy,因为您可以在JVM运行时更改类。