Ho cercato un po’ su Internet, ma non ho trovato un esempio d’uso di queste tecnologie messe insieme, perciò basandomi sullo stesso esempio usando Struts 2 ho deciso di scrivere questo articolo.
- creiamo in MySQL un database myDatabase, con myPassword e myUser
- Per prima cosa impostiamo l’ambiente di lavoro su Eclipse:
- creiamo sotto src i package it.stripes.action, it.stripes.entity, it.stripes.service
- creiamo sotto src la cartella META-INF e al suo interno creiamo un file di nome persistence.xml
- creiamo di fianco a web.xml il file applicationContext.xml
- copiamo nella cartella WEB-INF/lib le seguenti librerie
- antlr.jar
- asm.jar
- asm-attrs.jar
- cglib.jar
- commons-collections.jar
- commons-logging.jar
- cos.jar
- dom4j.jar
- ehchace.jar
- ejb3-persistence.jar
- hibernate3.jar
- hibernate-annotations.jar
- hibernate-commons-annotations.jar
- hibernate-entitymanager.jar
- javassist.jar
- jboss-archive-browsing.jar
- jstl.jar
- mysql-connector-java-x.x.x-bin.jar
- spring.jar
- standard.jar
- stripes.jar
- xml-apis.jar
- creiamo una cartella classes sotto WEB-INF e creiamoci dentro un file StripesResources.properties
- creiamo una pagina welcome.jsp sotto WebContent
- Mettiamo nel file web.xml questo codice:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>
net.sourceforge.stripes.controller.StripesFilter
</filter-class>
<init-param>
<param-name>ActionResolver.Packages</param-name>
<param-value>it.stripes.action</param-value>
</init-param>
<init-param>
<param-name>Interceptor.Classes</param-name>
<param-value>
net.sourceforge.stripes.integration.spring.SpringInterceptor,
net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>StripesFilter</filter-name>
<servlet-name>StripesDispatcher</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>StripesDispatcher</servlet-name>
<servlet-class>
net.sourceforge.stripes.controller.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StripesDispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>welcome.jsp</welcome-file>
</welcome-file-list>
</web-app>
- Mettiamo nel file StripesResources.properties questo codice (autoesplicativo):
###############################################################################
## Default Resource Bundle file for the Stripes Framework. Values should be
## placed in here for the following:
## - Form Field Labels, unless you want users to see a non-localized, non-
## pretty name from the form field declaration (prettied up a little).
## - Error messages for:
## - Standard validation error messages
## - Converter error messages
## - Error messages used in your custom ActionBean classes
###############################################################################
# Resource strings used by the <stripes:errors> tag when there are no nested tags
stripes.errors.header=
<div style="color:#b72222; font-weight: bold">Please fix the following errors:</div>
<ol>
stripes.errors.beforeError=
<li style="color: #b72222;">
stripes.errors.afterError=</li>
stripes.errors.footer=</ol>
# Resource strings used by the <stripes:errors> tag when displaying errors for a
# specific field (e.g. <stripes:errors field="password"/>). If not supplied the
# values above will be used instead.
stripes.fieldErrors.header=
stripes.fieldErrors.beforeError=<span style="color: #b72222;">
stripes.fieldErrors.afterError=</span>
stripes.fieldErrors.footer=
# Resource strings used by the stripes:messages tag
stripes.messages.header=
<ul class="messages">
stripes.messages.beforeMessage=
<li>
stripes.messages.afterMessage=</li>
stripes.messages.footer=</ul>
# Validation error messages produced by Stripes' built-in converter classes. These
# are default error messages and can be overridden on per-field and per-form levels.
# Using the 'invalidNumber' error for a field 'age' of a form posting to
# '/user/Profile.action', the keys looked for (in order) would be:
# 1: /user/Profile.action.age.invalidNumber
# 2: /user/Profile.action.age.errorMessage
# 3: age.errorMessage
# 4: /user/Profile.action.invalidNumber
# 5: converter.number.invalidNumber
converter.number.invalidNumber=The value ({1}) entered in field {0} must be a valid number
converter.byte.outOfRange=The value ({1}) entered in field {0} was out of the range {2} to {3}
converter.short.outOfRange=The value ({1}) entered in field {0} was out of the range {2} to {3}
converter.integer.outOfRange=The value ({1}) entered in field {0} was out of the range {2} to {3}
converter.float.outOfRange=The value ({1}) entered in field {0} was out of the range {2} to {3}
converter.enum.notAnEnumeratedValue=The value "{1}" is not a valid value for field {0}
converter.date.invalidDate=The value ({1}) entered in field {0} must be a valid date
converter.email.invalidEmail=The value ({1}) entered is not a valid email address
converter.creditCard.invalidCreditCard=The value ({1}) entered is not a valid credit card number
# Validation error messages produced by Stripes' annotation based validations. These
# are default error messages and can be overridden on per-field and per-form levels.
# Using the 'valueNotPresent' required field error for a field 'username' of a form
# posting to '/user/Register.action', the keys looked for (in order) would be:
# 1: /user/Register.action.username.valueNotPresent
# 2: /user/Register.action.username.errorMessage
# 3: username.errorMessage
# 4: /user/Register.action.valueNotPresent
# 5: validation.required.valueNotPresent
validation.required.valueNotPresent={0} is a required field
validation.minlength.valueTooShort={0} must be at least {2} characters long
validation.maxlength.valueTooLong={0} must be no more than {2} characters long
validation.minvalue.valueBelowMinimum=The minimum allowed value for {0} is {2}
validation.maxvalue.valueAboveMaximum=The maximum allowed value for {0} is {2}
validation.mask.valueDoesNotMatch=<em>{1}</em> is not a valid {0}
validation.expression.valueFailedExpression=The value supplied ({1}) for field {0} is invalid
validation.file.postBodyTooBig=Total upload size of {3} KB exceeds the maximum size of {2} KB
- Mettiamo nel persistence.xml questo codice:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="myDatabase" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.default_schema" value="myDatabase" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
</persistence>
- Mettiamo nell’applicationContext.xml questo codice:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="loginregister" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/myDatabase" />
<property name="username" value="myUser" />
<property name="password" value="myPassword" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="userService" class="it.stripes.service.UserServiceImpl" scope="singleton" />
</beans>
- Creiamo la nostra Entity che si chiama User
package it.stripes.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue
private Integer id;
private String nome;
private String cognome;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
}
- Creiamo l’interfaccia del servizio e il servizio che la implementa: UserService e UserServiceImpl
package it.stripes.service;
import it.stripes.entity.User;
import java.util.List;
public interface UserService {
public User find(Integer id);
public void salva(User u);
public void cancella(Integer id);
public List<User> findAll();
}
package it.stripes.service;
import it.stripes.entity.User;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class UserServiceImpl implements UserService {
private EntityManager em;
@Override
public void cancella(Integer id) {
em.remove(find(id));
}
@Override
public User find(Integer id) {
return em.find(User.class, id);
}
@Override
public List<User> findAll() {
Query q = em.createQuery("SELECT u FROM User u");
return q.getResultList();
}
@Override
public void salva(User u) {
if(u.getId() == null)
em.persist(u);
else
em.merge(u);
}
public EntityManager getEm() {
return em;
}
@PersistenceContext
public void setEm(EntityManager em) {
this.em = em;
}
}
- Creiamo l’ActionBean, che si chiamerà UserActionBean
package it.stripes.action;
import java.util.List;
import it.stripes.entity.User;
import it.stripes.service.UserService;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
public class UserActionBean implements ActionBean {
private ActionBeanContext context;
@SpringBean("userService" )
private UserService userService;
private Integer id;
private List<User> users;
@ValidateNestedProperties({
@Validate(field = "nome", required = true),
@Validate(field = "cognome", required = true) })
private User user;
@DefaultHandler
public Resolution salva() {
userService.salva(user);
users = userService.findAll();
return new ForwardResolution("/user-list.jsp");
}
@DontValidate
public Resolution modifica() {
user = userService.find(id);
return new ForwardResolution("/welcome.jsp");
}
@DontValidate
public Resolution cancella() {
userService.cancella(id);
users = userService.findAll();
return new ForwardResolution("/user-list.jsp");
}
@DontValidate
public Resolution nuovo() {
user = new User();
return new ForwardResolution("/welcome.jsp");
}
public ActionBeanContext getContext() {
return context;
}
public void setContext(ActionBeanContext context) {
this.context = context;
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
- Ora mettiamo nella pagina welcome.jsp questo codice
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<stripes:form action="/User.action">
<stripes:errors />
<table>
<tr>
<td><stripes:hidden name="user.id" /></td>
</tr>
<tr>
<td><stripes:label for="label.nome">Nome</stripes:label></td>
<td><stripes:text name="user.nome" /></td>
</tr>
<tr>
<td><stripes:label for="label.cognome">Cognome</stripes:label></td>
<td><stripes:text name="user.cognome" /></td>
</tr>
<tr>
<td><stripes:submit name="salva" value="Salva"/></td>
</tr>
</table>
</stripes:form>
</body>
</html>
- Ora creiamo una pagina user-list.jsp di fianco a welcome.jsp
<%@ taglib prefix="stripes"
uri="http://stripes.sourceforge.net/stripes.tld"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<stripes:link href="/User.action" event="nuovo">Nuovo utente</stripes:link>
<table>
<th>id</th>
<th>Nome</th>
<th>Cognome</th>
<c:forEach items="${actionBean.users}" var="user">
<tr>
<td><c:out value="${user.id}" /></td>
<td><c:out value="${user.nome}" /></td>
<td><c:out value="${user.cognome}" /></td>
<td><stripes:link href="/User.action" event="modifica">Modifica
<stripes:param name="id" value="${user.id}" />
</stripes:link></td>
<td><stripes:link href="/User.action" event="cancella">Cancella
<stripes:param name="id" value="${user.id}" />
</stripes:link></td>
</tr>
</c:forEach></table>
</body>
</html>
Bene, ora possiamo fare partire l’applicazione e tutto dovrebbe funzionare.