Creazione di una semplice web application utilizzando maven, jpa2, spring, struts2, mysql (parte 4)

Definito il nostro modello User, vogliamo creare alcuni servizi su di esso. In particolare vogliamo dare la possibilità al sistema di creare nuovi utenti, eliminarli, aggiornarli e prelevarli tutti in una lista.

Per fare questo creeremo un’interfaccia UserService.java.

package it.sample.webapp.service;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import it.sample.webapp.model.User;

public interface UserService {
  /**
   * Creates a new user
   * @param user new user to be created
   * @return updated user object that should be used for further updates
   * @throws javax.persistence.PersistenceException when the user can not be 
   *       persisted. This is a <code>RuntimeException</code>
   */
  public User createUser(User user);
  
  /**
   * Deletes the specified user
   * @param user user object to be deleted
   * @throws javax.persistence.PersistenceException when the user can not be 
   *       deleted. This is a <code>RuntimeException</code>
   */
  public void deleteUser(User user);
  
  /**
   * Updates the specified user
   * @param user user object to be updated
   * @return updated user object that should be used for further updates
   * @throws javax.persistence.PersistenceException when the user can not be 
   *       persisted. This is a <code>RuntimeException</code>
   */
  public User updateUser(User user);
  
  /**
   * Gets the user using specified user id
   * @param id unique id assigned to the user
   * @return <code>User</code> object; <code>null</code> if the user does not 
   *       exist in the database
   */
  public User getUser(Long id);
  
  /**
   * Gets all the users
   * @return list of all the users
   */
  public List<User> getAllUsers();
  
  /**
   * Gets the user using specified user name
   * @param name user's name
   * @return <code>User</code> object corresponding to the specified name; 
   *     <code>null</code> if the user does not exist in the database
   */
  public User getUserByUserName(String username);
}

									

L’interfaccia sarà poi implementata dalla classe UserServiceImpl.java

package it.sample.webapp.service.impl;

import java.util.List;

import javax.persistence.NoResultException;

import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;

import it.sample.webapp.dao.jpa.UserDao;
import it.sample.webapp.model.User;
import it.sample.webapp.service.UserService;

@Transactional
public class UserServiceImpl implements UserService{
  Logger  logger = Logger.getLogger(this.getClass());
  private UserDao userDao;
  
  @Override
  public User createUser(User user) {
    return userDao.save(user);
  }

  @Override
  public void deleteUser(User user) {
    userDao.delete(user.getId());
  }

  @Override
  public List<User> getAllUsers() {
    return userDao.getAll();
  }

  @Override
  public User getUser(Long id) {
    User user = null;
    try {
      user = userDao.getById(id);
    }
    catch (NoResultException nsre) {
      if (logger.isDebugEnabled()) {
        logger.debug("No user found for the specified ID : [" + id + "]");
      }
      user = null;
    }
    return user;
  }

  @Override
  public User updateUser(User user) {
    return userDao.save(user);
  }

  @Override
  public User getUserByUserName(String username) {
    User user = null;
    try {
      user = userDao.getByUserName(username);
    }
    catch (NoResultException nsre) {
      if (logger.isDebugEnabled()) {
        logger.debug("No user found for the specified Name : [" + username + "]");
      }
      user = null;
    }
    return user;
  }
  
  /**
   * Sets the DAO used by this service for persisting <code>User</code> object
   * @param userDao the user DAO to be used for persistence
   */
  public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
  }

  /**
   * Gets the <code>User</code> DAO used for persistence
   * @return the user DAO used for persistence
   */
  public UserDao getUserDao() {
    return userDao;
  }
}

									

Adesso creiamo una classe SampleAction richiamata da struts in modo da scrivere un minimo di logica di business.

Continua a leggere Creazione di una semplice web application utilizzando maven, jpa2, spring, struts2, mysql (parte 4)

Creazione di una semplice web application utilizzando maven, jpa2, spring, struts2, mysql (parte 3)

Ora possiamo iniziare a costruire la nostra applicazione.

Per prima cosa implementiamo il modello. Il nostro dominio in questo caso è l’utente e sarà rappresentato dalla classe User.java. Questa classe rappresenterà il nostro utente nel sistema. Verranno quindi implementati i metodi setter/getter che modificheranno le proprietà id, username, password

User.java

package it.sample.webapp.model;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * Defines a model that represents a user in the system.
 */

@Entity
@Table(name = "user")
public class User implements Serializable {
  private static final long serialVersionUID = -2230673925164485629L;
  
  @Id
  @GeneratedValue
  private Long id;
  
  private String username;
  private String password;

  
  

  /**
   * Sets the unique id for this user
   * @param id unique id to be assigned
   */
  public void setId(Long id) {
    this.id = id;
  }
  
  /**
   * Gets the unique id assigned to this user
   * @return the unique id
   */
  public Long getId() {
    return id;
  }
  
  /**
   * Gets the name of this user
   * @return the name
   */
  public final String getUsername() {
    return username;
  }
  
  /**
   * Sets the name of this user. 
   * @param name the name to set
   */
  public final void setUsername(String username) {
    this.username = username;
  }
  
  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }


}

									

A questo punto possiamo implementare gli oggetti DAO per l’accesso al DB.

Per fare questo implementiamo prima un’interfaccia generica che espone i metodi principali di accesso al DB (delete, getAll, getById,save) e poi una classe astratta che esegue un’implementazione di default della classe GenericDao. Ci preoccuperemo di implementare l’interfaccia in un secondo momento.

GenericDao.java

package it.sample.webapp.dao;

import java.io.Serializable;
import java.util.List;

/**
 * Defines a generic data access object that is extended by all the DAOs in the
 * system. This interface defines the common CRUD methods like <code>save</code>, 
 * <code>delete</code> <code>getAll</code> and <code>getById</code>.
 */
public interface GenericDao <T, ID extends Serializable> {
  
  /**
   * Gets the list of all objects of this type  
   * @return list of this objects; the list can be empty
   */
  public List<T>  getAll();
  
  /**
   * Gets the object using specified primary key
   * @param id primary key (ID) of the object to retrieve
   * @return object corresponding to the specified primary key (ID)
   * @throws javax.persistence.NoResultException when object
   *     corresponding to the specified ID (primary key) is not found. This is a
   *     <code>RuntimeException</code>
   */
  public T getById(ID id);
  
  /**
   * Saves the specified object. Handles both insert as well as update
   * @param object the object to save
   * @return managed copy of the original object. Use this object if you want 
   *       the future changes managed (persisted).
   * @throws javax.persistence.PersistenceException when the specified object
   *     could not be persisted. This is a
   *     <code>RuntimeException</code>
   */
  public T save(T  object);
  
  /**
   * Deletes the object that corresponds to the specified primary key (ID)
   * @param object the object to delete
   * @throws javax.persistence.PersistenceException when the specified object
   *     could not be deleted. This is a
   *     <code>RuntimeException</code>
   */
  public void delete(ID  id);
}

									

BaseJpaDao.java

package it.sample.webapp.dao.jpa;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import it.sample.webapp.dao.GenericDao;

/**
 * Defines a Base DAO that provides JPA implementation. 
 * This class keeps the reference to the <code>EntityManager</code> and 
 * provides a default implementation for methods defined in the <code>GenericDao</code>
 * interface.
 */
public abstract class BaseJpaDao<T, ID extends Serializable> implements GenericDao<T, ID> {
  private Class<T> persistentClass;
  protected EntityManager entityManager;

  /**
     * Constructor that takes in a class to see which type of entity to persist
     * @param persistentClass the class type you'd like to persist
     */
    public BaseJpaDao(final Class<T> persistentClass) {
        this.persistentClass = persistentClass;
    }
  
  /**
   * Gets the <code>EntityManager</code> used by this DAO
   * @return the entityManager used for persistence
   */
  public final EntityManager getEntityManager() {
    return entityManager;
  }

  /**
   * Sets the <code>EntityManager</code> used by this DAO
   * @param entityManager the entityManager to be used for persistence
   */
  @PersistenceContext
  public final void setEntityManager(EntityManager entityManager) {
    this.entityManager = entityManager;
  }
  
  @Override
  public void delete(ID id) {
    this.entityManager.remove(id);
    
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<T> getAll() {
    Query q = this.entityManager.createQuery("FROM " + 
                         this.persistentClass.getName());
    return q.getResultList();
  }

  @Override
  public T getById(ID id) {
    final T data= this.entityManager.find(persistentClass, id);
    return data;
  }

  @Override
  public T save(T object) {
    try {
    final T data = this.entityManager.merge(object);
    return data;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

}

									

Continua a leggere Creazione di una semplice web application utilizzando maven, jpa2, spring, struts2, mysql (parte 3)

Creazione di una semplice web application utilizzando maven, jpa2, spring, struts2, mysql (parte 2)

una volta configurato correttamente il file POM.xml possiamo iniziare la configurazione di tutti gli altri file necessari per il buon funzionamento della nostra applicazione web

Configurazione web.xml

sotto la cartella WEB-INF inserire il seguente file web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="web-app" version="2.4" 
         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">
  <display-name>Semplice WebApp usando struts, jpa, spring</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext*.xml</param-value>
    </context-param>
  
  <filter>
     <filter-name>struts-cleanup</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
  </filter>   
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
     <filter-name>struts-cleanup</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>   
    <!-- Listeners -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

									

Continua a leggere Creazione di una semplice web application utilizzando maven, jpa2, spring, struts2, mysql (parte 2)

Creazione di una semplice web application utilizzando maven, jpa2, spring, struts2, mysql

medium economic 1 day

In questo tutorial verrà spiegato come sviluppare una semplice web application utilizzando tecnologie come maven, jpa2, struts2, spring e mysql.

Ambiente di lavoro:

  • MySQL Server
  • Eclipse + da “Eclipse Market Place”  “Maven Integration for Eclipse”
  • JDK 1.7

Creazione tabella mysql:

Prima di iniziare tutto il lavoro creiamo una tabella che chiameremo user

CREATE  TABLE IF NOT EXISTS `user` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(255) NOT NULL ,
  `password` VARCHAR(255) ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;
									

 

Creazione di un nuovo progetto Maven su Eclipse:

– creiamo un nuovo progetto “maven” su eclipse

– impostiamo  maven-archetypes-webapp

– impostiamo grupId e artifactId come in figura



Struttura progetto e configurazione pom.xml

Una volta generato il progetto maven, Eclipse ci propone tutto il progetto come in figura

 Il prossimo passo sarà quello di configurare il file pom.xml in modo da personalizzare il building e includere le tecnologie che ci interessano.

In particolare includiamo le dipendenze per: struts2, spring, mysql connector, servlet e jsp, hibernate, log4j e junit.

Dopo di che impostiamo anche il <build> in modo da utilizzare alcuni plugin tra cui il web server jetty.

POM.XML

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>it.sample</groupId>
  <artifactId>webapp</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>webapp Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <struts2.version>2.1.8</struts2.version>
    <hibernate.em.version>3.4.0.GA</hibernate.em.version>
    <spring.version>2.5.6</spring.version>
        <spring.jpa.version>2.0.8</spring.jpa.version>
        <mysql.connector.version>5.1.13</mysql.connector.version>
    <junit.version>4.4</junit.version>
        <log4j.version>1.2.16</log4j.version>
  </properties>


  <dependencies>
        <!--  Struts 2 -->
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>${struts2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-spring-plugin</artifactId>
            <version>${struts2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-junit-plugin</artifactId>
            <version>${struts2.version}</version>
        </dependency>

        <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jpa</artifactId>
            <version>${spring.jpa.version}</version>
        </dependency>
        
        <!-- MySQL JDBC Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.connector.version}</version>
    </dependency>
        
        <!-- Servlet & Jsp -->
        <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>
        
        <!-- Hibernate dependencies -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.em.version}</version>
        </dependency>
 
        <!-- Other dependencies -->

        <!-- slf4j required for hibernate-annotations 3.4.0 -->    
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.5.6</version>
      </dependency>
      <!-- concrete Log4J Implementation for SLF4J API-->
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.5.6</version>
      </dependency>
        
      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>${log4j.version}</version>
          <scope>runtime</scope>
     </dependency>
  
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>${junit.version}</version>
          <scope>test</scope>
      </dependency>
  </dependencies>
  

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.0.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1-beta-1</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.0.0</version>
        <configuration>
          <contextPath>/</contextPath>
          <scanIntervalSeconds>3</scanIntervalSeconds>
          <scanTargets>
            <scanTarget>
              src/main/webapp/WEB-INF/web.xml
                  </scanTarget>
          </scanTargets>
        </configuration>
      </plugin>
        </plugins>
    <finalName>webapp</finalName>
  </build>

</project>

									

Sviluppo nuove customizzazioni su Adempiere, massima flessibilità e semplicità

Adempiere mette a disposizione degli sviluppatori alcuni tool che semplificano il processo di implementazione.

Se si vuole sviluppare una nuova feature la prima cosa da fare è modellizzare il database e creare lo strato di persistenza model all’interno del codice sorgente.

Come possiamo vedere dall’implementazione del configuratore di processo sono state create le classi model con i metodi modifiers getter e setter per la gestione dei dati. Queste classi rispecchiano il modello dati esistente sul database.

Ad esempio CP_ConfProc.java corrisponde alla tabella cp_confproc sul database, CP_ProcessFlow.java corrisponde alla tabella CP_ProcessFlow e così via.

Adempiere mette a disposizione degli sviluppatori alcuni strumenti che rendono più semplice e controllato lo sviluppo della parte model dell’applicazione. Basta quindi “costruire” il database della customizzazione (ricordarsi lo standard di implementazione delle tabelle: inserire il prefisso che ricoda il tipo di customizzazione e le colonne che devono essere obbligatoriamente presenti in ogni tabella).

Dal database è possibile “costruire” il “modello” dell’applicazione grazie ad una classe utility: /src/org/adempoiere/util/GenerateModel.java

Questa funzione permette la costruzione di tutte le classi che hanno come prefisso X_ e le interfaccie con prefisso I_ con i relativi getter e setter associati rispettivamente alla tabella ed alle colonne della customizzazione.

Le classi X_CP_ConfProc.java e I_CP_ConfProc.java sono autogenerate dal GenerateModel.

sezione del GenerateModel.java

    String tableLike = null;
    tableLike = "'%'";  //  All tables
    // tableLike = "'AD_OrgInfo', 'AD_Role', 'C_CashLine', 'C_Currency', 'C_Invoice', 'C_Order', 'C_Payment', 'M_InventoryLine', 'M_PriceList', 'M_Product', 'U_POSTerminal'";  //  Only specific tables
    if (args.length > 3)
      tableLike = args[3];
    log.info("Table Like: " + tableLike);

    //  complete sql
    sql.insert(0, "SELECT AD_Table_ID "
      + "FROM AD_Table "
      + "WHERE (TableName IN ('RV_WarehousePrice','RV_BPartner')"  //  special views
      + " OR IsView='N')"
      + " AND IsActive = 'Y' AND TableName NOT LIKE '%_Trl' AND ");
    // Autodetect if we need to use IN or LIKE clause - teo_sarca [ 3020640 ]
    if (tableLike.indexOf(",") == -1)
      sql.append(" AND TableName LIKE ").append(tableLike);
    else
      sql.append(" AND TableName IN (").append(tableLike).append(")"); // only specific tables

    sql.append(" ORDER BY TableName");
    
    //
    int count = 0;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try
    {
      pstmt = DB.prepareStatement(sql.toString(), null);
      rs = pstmt.executeQuery();
      while (rs.next())
      {
        new ModelInterfaceGenerator(rs.getInt(1), directory, packageName);
        new ModelClassGenerator(rs.getInt(1), directory, packageName);
        count++;
      }
     }
    catch (Exception e)
    {
      log.log(Level.SEVERE, sql.toString(), e);
    }
    finally
    {
      DB.close(rs, pstmt);
      rs = null; pstmt = null;
    }
    log.info("Generated = " + count);
  }