Weitere ähnliche Inhalte Ähnlich wie Lightweight javaEE with Guice (20) Mehr von Peerapat Asoktummarungsri (13) Kürzlich hochgeladen (20) Lightweight javaEE with Guice2. About Me
CTO & Co-Founder @ Signature App House
Software Architecture @ FICO.com
Blogger at thjug.blogspot.com
Twitter Addict
Programmer lover <3
(c) copyright 2013 nuboat in wonderland
Sunday, June 16, 13
3. Requirement
Java SDK 7u21 or latest
Netbeans JavaEE 7.3 or latest
PostgreSQL 9.2 or latest
Chrome Browser latest version
Postman - REST Client
(c) copyright 2013 nuboat in wonderland
Sunday, June 16, 13
4. Topics
Netbeans - Create Development Test Deploy
Maven - Library Management
Servlet + JAX-RS - RESTful Webservice
Guice - Transaction & Dependency Injection
JPA - Object Relational Mapping
Shiro - Encrypt Password
TestNG - Unit Test Framework
(c) copyright 2013 nuboat in wonderland
Sunday, June 16, 13
5. Netbeans
NetBeans IDE lets you quickly and easily develop Java desktop, mobile, and
web applications, while also providing great tools for PHP and C/C++
developers. It is free and open source and has a large community of users
and developers around the world.
Best Support for Latest Java Technologies
NetBeans IDE provides first-class comprehensive support for the newest
Java technologies and latest Java enhancements before other IDEs. It is the
first IDE providing support for JDK 7, Java EE 7, and JavaFX 2.
With its constantly improving Java Editor, many rich features and an
extensive range of tools, templates and samples, NetBeans IDE sets the
standard for developing with cutting edge technologies out of the box
Sunday, June 16, 13
6. Maven
Standard Build Infrastructure
Build Tool
Dependency Management Tool
Quality Tool
Opensource Apache Project
(c) copyright 2013 nuboat in wonderland
http://thjug.blogspot.com/2013/04/what-is-maven-1.html
Sunday, June 16, 13
7. MVN Standard Directory
(c) copyright 2013 nuboat in wonderland
my-app
|-- pom.xml
|-- target
|-- src
|-- main
| `-- java
| `-- resources
| `-- webapp
|
|-- test
`-- java
`-- resources
Sunday, June 16, 13
8. Jersey
Jersey is the open source, production quality, JAX-RS (JSR 311 & JSR 339)
Reference Implementation for building RESTful Web services. But, it is also
more than the Reference Implementation. Jersey provides an API so that
developers may extend Jersey to suit their needs.
Sunday, June 16, 13
9. Guice
Google Guice (pronounced "juice")[1] is an open source software
framework for the Java platform released by Google under the Apache
License. It provides support for dependency injection using annotations to
configure Java objects.[2] Dependency injection is a design pattern whose
core principle is to separate behavior from dependency resolution.
Example
@InjectLogger Logger logger;
@Inject SigninFacade facade;
@Inject EntityManager em;
Sunday, June 16, 13
10. JPA
Development of a new version of JPA, namely JPA 2.0 JSR 317 was started
in July 2007. JPA 2.0 was approved as final on December 10, 2009.
The focus of JPA 2.0 was to address features that were present in some of
the popular ORM vendors but couldn't gain consensus approval for JPA 1.0.
The main features included in this update are:
• Expanded object-relational mapping functionality
• support for collections of embedded objects, linked in the ORM with a
many-to-one relationship
• multiple levels of embedded objects
• ordered lists
• combinations of access types
• A criteria query API
• standardization of query 'hints'[clarify]
• standardization of additional metadata to support DDL generation
• support for validation
Sunday, June 16, 13
13. pom.xml
Model Attribute
(c) copyright 2013 nuboat in wonderland
<modelVersion>4.0.0</modelVersion>
<groupId>com.thjug</groupId>
<artifactId>Services</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Services</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Sunday, June 16, 13
14. pom.xml
Repositories Attribute
(c) copyright 2013 nuboat in wonderland
! <repositories>
! ! <repository>
! ! ! <id>EclipseLink</id>
! ! ! <url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
! ! </repository>
! </repositories>
Sunday, June 16, 13
15. pom.xml
Servlet Dependency
(c) copyright 2013 nuboat in wonderland
! ! <dependency>
! ! ! <groupId>org.apache.openejb</groupId>
! ! ! <artifactId>javaee-api</artifactId>
! ! ! <version>6.0-5</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>com.sun.jersey</groupId>
! ! ! <artifactId>jersey-server</artifactId>
! ! ! <version>1.17.1</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>com.sun.jersey</groupId>
! ! ! <artifactId>jersey-servlet</artifactId>
! ! ! <version>1.17.1</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>com.sun.jersey.contribs</groupId>
! ! ! <artifactId>jersey-guice</artifactId>
! ! ! <version>1.17.1</version>
! ! </dependency>
Sunday, June 16, 13
16. pom.xml
Common Dependency
(c) copyright 2013 nuboat in wonderland
! ! <dependency>
! ! ! <groupId>commons-lang</groupId>
! ! ! <artifactId>commons-lang</artifactId>
! ! ! <version>2.6</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>commons-io</groupId>
! ! ! <artifactId>commons-io</artifactId>
! ! ! <version>2.4</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>commons-fileupload</groupId>
! ! ! <artifactId>commons-fileupload</artifactId>
! ! ! <version>1.3</version>
! ! </dependency>
Sunday, June 16, 13
17. pom.xml
Guice Dependency
(c) copyright 2013 nuboat in wonderland
! ! <dependency>
! ! ! <groupId>com.google.inject</groupId>
! ! ! <artifactId>guice</artifactId>
! ! ! <version>3.0</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>com.google.inject.extensions</groupId>
! ! ! <artifactId>guice-servlet</artifactId>
! ! ! <version>3.0</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>com.google.inject.extensions</groupId>
! ! ! <artifactId>guice-persist</artifactId>
! ! ! <version>3.0</version>
! ! </dependency>
Sunday, June 16, 13
18. pom.xml
Model Dependency
(c) copyright 2013 nuboat in wonderland
! ! <dependency>
! ! ! <groupId>postgresql</groupId>
! ! ! <artifactId>postgresql</artifactId>
! ! ! <version>9.1-901-1.jdbc4</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>org.eclipse.persistence</groupId>
! ! ! <artifactId>eclipselink</artifactId>
! ! ! <version>2.5.0</version>
! ! ! <exclusions>
! ! ! ! <exclusion>
! ! ! ! ! <artifactId>commonj.sdo</artifactId>
! ! ! ! ! <groupId>commonj.sdo</groupId>
! ! ! ! </exclusion>
! ! ! </exclusions>
! ! </dependency>
Sunday, June 16, 13
19. pom.xml
Logging Dependency
(c) copyright 2013 nuboat in wonderland
! ! <dependency>
! ! ! <groupId>ch.qos.logback</groupId>
! ! ! <artifactId>logback-classic</artifactId>
! ! ! <version>1.0.13</version>
! ! </dependency>
! ! <dependency>
! ! ! <groupId>commons-logging</groupId>
! ! ! <artifactId>commons-logging</artifactId>
! ! ! <version>1.1.3</version>
! ! </dependency>
Sunday, June 16, 13
20. pom.xml
Security Dependency
(c) copyright 2013 nuboat in wonderland
! ! <dependency>
! ! ! <groupId>org.apache.shiro</groupId>
! ! ! <artifactId>shiro-core</artifactId>
! ! ! <version>1.2.2</version>
! ! </dependency>
Sunday, June 16, 13
21. pom.xml
Test Dependency
(c) copyright 2013 nuboat in wonderland
! ! <dependency>
! ! ! <groupId>org.testng</groupId>
! ! ! <artifactId>testng</artifactId>
! ! ! <version>6.8.5</version>
! ! ! <scope>test</scope>
! ! </dependency>
Sunday, June 16, 13
22. web.xml
(c) copyright 2013 nuboat in wonderland
! <display-name>Services</display-name>
! <filter>
! ! <filter-name>guiceFilter</filter-name>
! ! <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
! </filter>
! <filter-mapping>
! ! <filter-name>guiceFilter</filter-name>
! ! <url-pattern>/*</url-pattern>
! </filter-mapping>
! <listener>
! ! <description>Guice Initiate</description>
! ! <listener-class>com.thjug.base.ServletContextListener</listener-class>
! </listener>
! <welcome-file-list>
! ! <welcome-file>index.jsp</welcome-file>
! </welcome-file-list>
Sunday, June 16, 13
23. web.xml
(c) copyright 2013 nuboat in wonderland
! <display-name>Services</display-name>
! <filter>
! ! <filter-name>guiceFilter</filter-name>
! ! <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
! </filter>
! <filter-mapping>
! ! <filter-name>guiceFilter</filter-name>
! ! <url-pattern>/*</url-pattern>
! </filter-mapping>
! <listener>
! ! <description>Guice Initiate</description>
! ! <listener-class>com.thjug.base.ServletContextListener</listener-class>
! </listener>
! <welcome-file-list>
! ! <welcome-file>index.jsp</welcome-file>
! </welcome-file-list>
Sunday, June 16, 13
24. logback.xml
(c) copyright 2013 nuboat in wonderland
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
! <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
! ! <layout class="ch.qos.logback.classic.PatternLayout">
! ! ! <Pattern>%d{HH:mm:ss.SSS} %logger{0} - %msg%n</Pattern>
! ! </layout>
! </appender>
! <logger name="com.thjug" level="DEBUG"/>
! <root level="debug">
! ! <appender-ref ref="STDOUT" />
! </root>
</configuration>
Sunday, June 16, 13
25. persistence.xml
(c) copyright 2013 nuboat in wonderland
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/
persistence/persistence_2_0.xsd">
! <persistence-unit name="dbUnit" transaction-type="RESOURCE_LOCAL">
! ! <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
! ! <class>com.thjug.entity.Account</class>
! ! <class>com.thjug.entity.History</class>
! ! <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
! ! <properties>
! ! ! <property name="eclipselink.logging.level" value="FINE"/>
! ! ! <property name="eclipselink.logging.parameters" value="true"/>
! ! ! <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
! ! ! <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/training"/>
! ! ! <property name="javax.persistence.jdbc.user" value="training"/>
! ! ! <property name="javax.persistence.jdbc.password" value="password"/>
! ! </properties>
! </persistence-unit>
</persistence>
Sunday, June 16, 13
26. (c) copyright 2013 nuboat in wonderland
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.persist.jpa.JpaPersistModule;
import com.google.inject.servlet.GuiceServletContextListener;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.thjug.restws.Echo;
import com.thjug.restws.Signin;
import com.thjug.restws.Status;
public class ServletContextListener extends GuiceServletContextListener {
! @Override
! protected Injector getInjector() {
! ! final Injector injector = Guice.createInjector(new JerseyServletModule() {
! ! ! @Override
! ! ! protected void configureServlets() {
! ! ! ! bind(Echo.class);
! ! ! ! bind(Status.class);
! ! ! ! bind(Signin.class);
! ! ! ! bind(ServletContainer.class).in(Singleton.class);
! ! ! ! serve("/rest/*").with(GuiceContainer.class);
! ! ! }
! ! }, new JpaPersistModule("dbUnit"));
! ! injector.getInstance(JPAInitializer.class);
! ! return injector;
! }
}
ServletContextListener.java
Sunday, June 16, 13
27. (c) copyright 2013 nuboat in wonderland
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.persist.PersistService;
@Singleton
public final class JPAInitializer {
! @Inject
! public JPAInitializer(final PersistService service) {
! ! service.start();
! }
}
JPAInitializer.java
Sunday, June 16, 13
28. (c) copyright 2013 nuboat in wonderland
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
@Path("/status")
public final class Status {
! @GET
! public final Response getJson() {
! ! return Response.status(200).entity("live!").build();
! }
}
Status.java
Sunday, June 16, 13
29. (c) copyright 2013 nuboat in wonderland
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Path("/echo")
public final class Echo {
! private static final Logger LOG = LoggerFactory.getLogger(Echo.class);
! @GET
! @Path("/{param}")
! @Produces(MediaType.APPLICATION_JSON)
! public final Response getJson(@PathParam("param") final String msg) {
! ! final String echomsg = msg.length() <= 24 ? msg : msg.substring(0, 24);
! ! LOG.info("Echo: {}", echomsg);
! ! return Response.status(200).entity(echomsg).build();
! }
}
Echo.java
Sunday, June 16, 13
30. (c) copyright 2013 nuboat in wonderland
import com.google.inject.Inject;
import com.thjug.facade.SigninFacade;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Path("/signin")
public final class Signin {
! private static final Logger LOG = LoggerFactory.getLogger(Signin.class);
! @Inject
! private SigninFacade facade;
! @POST
! public final Response getJson(
! ! ! @FormParam("username") final String username,
! ! ! @FormParam("password") final String password) {
! ! LOG.info("Username: {} Password: {}", username, password);
! ! String result;
! ! try {
! ! ! result = (facade.authen(username, password)) ? "pass" : "fail";
! ! } catch (final Exception e) {
! ! ! LOG.error(e.getMessage(), e);
! ! ! result = e.getMessage();
! ! }
! ! return Response.status(200).entity(result).build();
! }
}
Signin.java
Sunday, June 16, 13
31. (c) copyright 2013 nuboat in wonderland
public enum Enable {
! T('T', "True"),
! F('F', "False");
! private char id;
! private String text;
! private Enable(final char id, final String text) {
! ! this.id = id;
! ! this.text = text;
! }
! public char getId() {
! ! return id;
! }
! public String getText() {
! ! return text;
! }
}
Enum - Enable.java
Sunday, June 16, 13
32. (c) copyright 2013 nuboat in wonderland
@Entity
@Table(name = "ACCOUNT")
@NamedQueries({
! @NamedQuery(name = Account.countAll, query = "SELECT COUNT(a) FROM Account a"),
! @NamedQuery(name = Account.findByUsername, query = "SELECT a FROM Account a WHERE
UPPER(a.username) = ?1"),})
public class Account implements Serializable {
! private static final long serialVersionUID = 1L;
! public static final String countAll = "Account.countAll";
! public static final String findByUsername = "Account.findByUsername";
! @Id
! @Basic(optional = false)
! @NotNull
! @Column(name = "id", nullable = false)
! @SequenceGenerator(name = "account_seq_gen", sequenceName = "account_id_seq", allocationSize = 1)
! @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "account_seq_gen")
! private Integer id;
.......
! @Basic(optional = false)
! @NotNull
! @Size(min = 1, max = 64)
! @Column(name = "username")
! private String username;
......
Entity - Account.java
Sunday, June 16, 13
33. (c) copyright 2013 nuboat in wonderland
@Inject
! private transient Provider<EntityManager> provider;
! public T create(final T entity) {
! ! getEntityManager().persist(entity);
! ! return entity;
! }
! public T find(final Object id) {
! ! return getEntityManager().getReference(entityClass, id);
! }
! public T edit(final T entity) {
! ! return getEntityManager().merge(entity);
! }
! public void remove(final T entity) {
! ! getEntityManager().remove(getEntityManager().merge(entity));
! }
! protected EntityManager getEntityManager() {
! ! return this.provider.get();
! }
CRUD - Create Read Update Delete
Sunday, June 16, 13
34. (c) copyright 2013 nuboat in wonderland
! protected <S> S findOne(final String namequery, final Object... param) {
! ! final Query q = getEntityManager().createNamedQuery(namequery);
! ! for (int i = 0; i < param.length; i++) {
! ! ! q.setParameter(i + 1, param[i]);
! ! }
! ! return (S) q.getSingleResult();
! }
! protected List<T> findAll(final String namequery, final Object... param) {
! ! final Query q = getEntityManager().createNamedQuery(namequery);
! ! for (int i = 0; i < param.length; i++) {
! ! ! q.setParameter(i + 1, param[i]);
! ! }
! ! return q.getResultList();
! }
! protected List<T> findRange(final String namequery, final int offset, final int limit, final Object... param) {
! ! final Query q = getEntityManager().createNamedQuery(namequery);
! ! for (int i = 0; i < param.length; i++) {
! ! ! q.setParameter(i + 1, param[i]);
! ! }
! ! if (limit != 0) {
! ! ! q.setMaxResults(limit);
! ! }
! ! if (offset != 0) {
! ! ! q.setFirstResult(offset);
! ! }
! ! return q.getResultList();
! }
AbstractService<T>.java
Sunday, June 16, 13
35. (c) copyright 2013 nuboat in wonderland
Facade Pattern
http://java.dzone.com/articles/design-patterns-uncovered-1
Sunday, June 16, 13
36. (c) copyright 2013 nuboat in wonderland
Facade Pattern in Project
Signin SigninFacade
SigninService
HistoryService
Client Facade
Class 1
Class 2
Sunday, June 16, 13
37. (c) copyright 2013 nuboat in wonderland
import com.google.inject.ImplementedBy;
import com.thjug.facade.impl.SigninFacadeImpl;
@ImplementedBy(value = SigninFacadeImpl.class)
public interface SigninFacade {
! public boolean authen(final String username, final String password)
! ! ! throws Exception;
}
SigninFacade.java
Sunday, June 16, 13
38. (c) copyright 2013 nuboat in wonderland
import com.thjug.facade.*;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import com.thjug.entity.Account;
import com.thjug.service.AccountService;
import org.apache.shiro.crypto.hash.Sha256Hash;
public class SigninFacadeImpl implements SigninFacade {
! @Inject
! AccountService accountService;
! @Inject
! HistoryService historyService;
! @Override
! @Transactional
! public boolean authen(final String username, final String password)
! ! ! throws Exception {
! ! final Account account = accountService.findByUsername(username.toUpperCase());
! ! final String cyphertext = new Sha256Hash(password).toHex();
! ! final boolean result = (cyphertext.equals(account.getPasswd())) ? true : false;
! ! historyService.keepLog("authen", account, Boolean.toString(result));
! ! return result;
! }
}
SigninFacadeImpl.java
Sunday, June 16, 13
39. (c) copyright 2013 nuboat in wonderland
import com.thjug.entity.Account;
public class AccountService extends AbstractService<Account> {
! public AccountService() {
! ! super(Account.class);
! }
! public Account findByUsername(final String username) throws Exception {
! ! return findOne(Account.findByUsername, username);
! }
}
AccountService.java
Sunday, June 16, 13
40. (c) copyright 2013 nuboat in wonderland
import com.thjug.entity.Account;
import com.thjug.entity.History;
public class HistoryService extends AbstractService<History> {
! public HistoryService() {
! ! super(History.class);
! }
! public void keepLog(final String action, final Account account, final String result) {
! ! // TODO
! }
}
HistoryService.java
Sunday, June 16, 13
41. (c) copyright 2013 nuboat in wonderland
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.persist.jpa.JpaPersistModule;
import com.thjug.base.JPAInitializer;
public abstract class AbstractFacadeNGTest {
! protected final Injector injector;
! public AbstractFacadeNGTest() {
! ! injector = Guice.createInjector(new JpaPersistModule("dbUnit"));
! ! injector.getInstance(JPAInitializer.class);
! }
}
AbstractFacadeNGTest.java
Sunday, June 16, 13
42. (c) copyright 2013 nuboat in wonderland
import static org.testng.Assert.*;
import org.testng.annotations.Test;
public class SigninFacadeImplNGTest extends AbstractFacadeNGTest {
! @Test
! public void testAuthen() throws Exception {
! ! String username = "admin";
! ! String password = "password";
! ! SigninFacadeImpl instance = injector.getInstance(SigninFacadeImpl.class);
! ! boolean expResult = true;
! ! boolean result = instance.authen(username, password);
! ! assertEquals(result, expResult);
! }
}
SigninFacadeImplNGTest.java
Sunday, June 16, 13