Fubbyo in action

Luglio 10, 2008

Stripes + Hibernate + JPA + Spring CRUD

Archiviato in: Stripes, hibernate, jpa, spring — fubbyo @ 7:27 am

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.

Nessun Commento »

Non c’è ancora nessun commento.

RSS feed dei commenti a questo articolo. TrackBack URI

Lascia un commento

Blog su WordPress.com.