Apache Pluto provides you a vast amount of integration types that you could use when it comes to deal with the Portlet development missions. We’ve previously, introduced you different types of Portlets; Standard Portlet (JSR286), JSP & Servlet, JSF 2.0, Struts 2.0, PHP 5 and now a Portlet of type Groovy.
Groovy is a Java Virtual Language (JVM) that’s working inside a JVM seamlessly like any Java Class you may write. Apache Pluto provides you a Groovy Bridge that enables you exposing a Groovy Portlet into your Portal Page without any need for additional cosmetics.
This tutorial is intended for providing you a full-fledged example for registering employees, in which an initial page will be displayed for employee’s information gathering. Once the user has submitted the form the employee registration will start and the confirmation message will be displayed too.
Project Structure
This figure below should help you recognize one of the best location for putting your Groovy classes as well as showing you the different accompanies files for the project.
Employee Table
As being we have a registration employee form, let’s look at the form of the Employee Table and its relevant columns.
As also, you can use below SQL create statement to get Employee Table created into your 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;
Employee Model
In the MVC design pattern and according for the concept of Separation of Concern, we must have an Employee Model that it takes the form of:
Employee.java
package com.journaldev.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;
}
}
This model will hold the data that’s going back and forth between the different components defined in the application.
Install Groovy Plugin Into Your Eclipse
To make sure you’re able of getting Groovy sources inside your Maven project, you must install Eclipse Groovy Plugin into your Eclipse IDE.
Installing of Eclipse Plugin wouldn’t take much time as you can do that by using the Eclipse install new software facility.
- From help menu, choose Install New Software.
- Paste copied link into Work with input and waiting until Eclipse show you the listed supposed updates that plugin contains.
- Select Groovy-Eclipse (Required) & Click next.
- Proceed until your eclipse has installed the Groovy Plugin and restart your Eclipse to make sure your installed Plugin takes effect.
- Now, from your Maven Project (That you’ve created before), create a Groovy class normally.
RegisterEmployeePortlet Groovy Portlet
RegisterEmployeePortlet will be built using the same manner that’s happened inside our introduced JSP & Servlet example. One major difference that it’s now a Groovy class, where no need for a package declaration nor for a variable types.
You may write a code analogous for what you’ve written inside your RegisterEmployeePortlet Java class, but for make a distinction we removed those optional constructs that Groovy doesn’t require.
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());
}
}
}
Here’s detailed explanation for the code mentioned above:
- RegisterEmployeePortlet Groovy class doesn’t reference a package, as it’s contained inside your resources in the Project Structure above.
- Groovy is a dynamic language, and so, it’s applicable for you to miss out in the variable types. Alternatively, you must use a def keyword and the Groovy engine would expect the type of the variable from the context.
- Groovy class is also able of accessing any defined Servlet inside your application.
RegisterEmployeePortlet Groovy Portlet Descriptor
As you’ve already used a Groovy class for creating a Portlet to be consumed by Apache Pluto, you know that the Portlet must be mentioned in the Portlet deployment descriptor (Portlet.xml).
The definition of Groovy Portlet inside your Portlet descriptor is little bit different as it’s also contained for additional detailes you must be aware of. Let’s first look at the Portlet.xml and see what are the major differences.
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>
Here’s detailed explanation for the code mentioned above:
- Your Groovy Portlet should be of org.apache.portals.bridge.groovy.GroovyPortlet class.
- You must provide the script-source which will be used later on for specifying the Groovy class that’s responsible of handling the initiated Portlet request.
- You have the ability of providing an optional auto-refresh parameter for enabling applying your modifications instantly. So, just make your modification and refresh the Portlet to get it executed directly.
- Script-source parameter accepts different types of paths; full physical file, url, uri or by using the reserved keyword classpath as be shown.
Application Deployment Descriptor & Maven Build File
There is no any change on the web deployment descriptor, the same file is used as it’s defined in the JSP & Servlet Tutorial.
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.journaldev.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.tld</taglib-location>
</taglib>
</web-app>
Just note that Apache Pluto assemble plugin will add some fragments into your web.xml while it builds the application for making the Portlet accessible.
At the other hand, the all required dependencies are maintained by the Maven build file, look below at the used 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.journaldev</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 – Database Handling
EmployeeDAO.java
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, 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.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;
}
}
RegisterEmployeeServlet – Business Handling
If you have noticed that the Groovy class hasn’t provided any code relevant for the registration process, on the contrary, it’s used mainly for handling the required business delegation and the actual work of employee registration got defined inside our RegisterEmployeeServlet, that’s applying the concept of Separation of concern (Soc). Look at below:
RegisterEmployeeServlet.java
package com.journaldev.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.journaldev.dao.EmployeeDAO;
import com.journaldev.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 Views
As you’ve noticed above, your Groovy Portlet has delegated the control into three different JSP pages:
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="https://www.journaldev.com/5097/<%=request.getContextPath()%>/images/success.jpg" name="<portlet:namespace/>Success"/>
<body>
<span>Congratulations ! you've just add a new employee</span><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>
<span>Unfortunately ! you may not be able of registering a new employee cause the reason below</span>
<br/>
<br/>
<img src="https://www.journaldev.com/5097/<%=request.getContextPath()%>/images/failed.jpg" name="<portlet:namespace/>Failed"/>
<span style="font-size:small ;font-style: italic;color: red;font-weight: bold;">
<%=renderRequest.getAttribute("exception")%>
</span>
<br/>
<br/>
<a href="<%=registerAnother%>">Try Again</a>
</body>
</html>
Employee Registration Demo
Before getting started demonstrate the employee registration sample, you must have an installed instance of Apache Pluto as well as a JournalDev Portal page. If you didn’t create it before, you need to return back into Apache Pluto Introduction for getting everything done.
And you should be able of seeing a new Employee saved against your database:
And if you’ve tried to register the user with the same used ID, you should be able of seeing a message tells you the actual cause of error.
Summary
Groovy is a dynamic JVM language, it’s amazing as you don’t need to be aware of a lot of things you must be aware of when you’re going to use Java language. If you want a Portlet that provides you the maximum gauge of Dynamicity, choose the Groovy as you can change your classes while your JVM is running.
Contribute us by commenting below and find below downloaded source code for your practice.