Showing posts with label Spring boot. Show all posts
Showing posts with label Spring boot. Show all posts

Friday, August 19, 2016

Jersey in spring boot – Hello world example

Simply speaking:

JAX-RS, namely Java API for RESTful Service,  is from JSR 311 (obsolete) and JSR 339 (download here).

Jersey is an reference implementation of JAX-RS.

Spring boot sure can implement REST service without Jersey by using the controller way (@RestConroller). Also, jersey can be chosen for exposing the RESTful services.

This is a hello world level example of using Jersey with spring boot to provide RESTful services.

0. what you need

In this demo, following are used:

  • java 8
  • maven 3.2
  • spring boot 1.4.0.RELEASE

Jersey is included in spring boot release.

1. Maven pom.xml

Only one dependency is needed.

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.shengwang.demo</groupId>
  <artifactId>rest-versioning</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <name>rest-versioning</name>
  <description>Demo project for spring boot jersey rest</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
    <relativePath/>
  </parent>

  <properties>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>

    <dependency>
	  <!-- only dependency needed -->
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jersey</artifactId>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

2. Java classes

In this hello world example, there are 5 classes totally.

  • Main class
  • POJO model class
  • Service
  • Jersey configuration
  • Endpoint

They will be shown one by one. The Jersey configuration and Endpoint class are more interesting, but for the completion for the demo, all classes are listed below.

2.1 Main class

This class is just a trival main class from spring boot.

package com.shengwang.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootJerseyApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootJerseyApplication.class, args);
  }
}

2.2.  POJO model

For demo usage. A model class is created. It’s just a POJO.

package com.shengwang.demo.model;

public class User {

  private String name;
  private int age;

  public User(String name, int age) {
    this.name = name;
    this.age = age;
  }
  
  // setter, getter ignored
}

2.3 Service class

A demo class just return a User object by a userId.

package com.shengwang.demo.service;

import com.shengwang.demo.model.User;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserService {
  private Map<String,User> users;

  @PostConstruct
  private void loadUser() {
    users = new HashMap<>();
    users.put("1",new User("Tom",20));
    users.put("2",new User("Jerry",19));
  }

  public User findById(String id) {
    return users.get(id);
  }
}

2.4 Jersey configuration

package com.shengwang.demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

@Component
@ApplicationPath("/v1")
public class JerseyConfig extends ResourceConfig {

  @Autowired
  public JerseyConfig(ObjectMapper objectMapper) {
    // register endpoints
    packages("com.shengwang.demo");
    // register jackson for json 
    register(new ObjectMapperContextResolver(objectMapper));
  }

  @Provider
  public static class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public ObjectMapperContextResolver(ObjectMapper mapper) {
      this.mapper = mapper;
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
      return mapper;
    }
  }
}

The JerseyConfig extends from jersey ResourceConfig, just register the endpoints and jackson for json.

2.5 Endpoint

Just like the spring controller, the jersey endpoint provides the URL mapping.

package com.shengwang.demo.endpoint;

import com.shengwang.demo.model.User;
import com.shengwang.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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;


@Component
@Path("/users")
public class DemoEndpoint {

  @Autowired
  private UserService userService;

  @GET
  @Path("/{id}")
  @Produces(MediaType.APPLICATION_JSON)
  public User getEventVersion1(@PathParam("id") String id) {
    return userService.findById(id);
  }
}

Now everything is ready, the whole project looks like below.

Capture

3. Run it

Start the spring boot application from your IDE, and access the url from a brower. Here is the json result you get:

image

Tuesday, February 16, 2016

How to use H2 embeded database in spring application

H2, as a embeded memory database, is mainly used for development and test phase. H2 also has a web console which is very convenient.

image

1. Use H2 in Spring boot application

Spring boot has almost everything done for you. You need to do 2 steps, first inluce H2 in you pom.xml.

  <!-- H2 -->
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <scope>runtime</scope>
  </dependency>

The version of H2 is managed by spring boot and  scope can be set to runtime because you code should not have any APIs come from H2 itself. Then specify datasource url to use H2 in the application.properties file or in lieu of yaml styled configuration

# define DataSrouce properties 
# use h2 can have a buid in web console http://localhost:8080/h2-console
spring.datasource.url=jdbc:h2:mem:mydb

In spring boot application, there is no need to set username and password for using H2 memory database, because H2's default username is 'sa' (or SA, case insensitive), default password is empty. These default username/password will be auto configured by spring boot.  Also Spring boot will config the H2 web console for you automatcally at http://localhost:8080/h2-console

Use H2 in spring-mvc application (non-spring boot)

In non-spring boot application, which is normall just powered by spring-webmvc and other spring artifacts, using H2 need 3 steps. First is also to include H2 in pom.xml

  <!-- H2 -->
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <version>1.4.190</version>
  </dependency>

Secondly,  use H2 in any ORM configuration. For example if your project uses JPA as persistence and uses Hibernate as JPA service provider. The JPA's configuration file /META-INF/persistence.xml may looks like below.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
 xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
 <persistence-unit name="spring-persistence-jpa-tx" transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <exclude-unlisted-classes>false</exclude-unlisted-classes>
  <properties>
   <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
   <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:mydb" />
   <property name="javax.persistence.jdbc.user" value="sa" />
   <property name="javax.persistence.jdbc.password" value="" />
   
   <!-- Automatically drop then create table -->
   <property name="hibernate.hbm2ddl.auto" value="create" />
   <!-- print out sql  -->
   <property name="hibernate.show_sql" value="true"/>
  </properties>
 </persistence-unit>
</persistence>

Specify the jdbc driver, jdbc url and etc , just like other database.

Finally, and optionally, If you want the H2 web console, you need to add a bean into spring context. In xml-styled spring configuration file, it looks like below.

 <bean id="h2WebServer" class="org.h2.tools.Server" factory-method="createWebServer"
  init-method="start" destroy-method="stop">
  <constructor-arg value="-web,-webAllowOthers,-webDaemon,-webPort,8082" />
 </bean>
In java-styled spring configuration, it looks like below.
@Configuration
@ComponentScan
public class JavaConfiguration {
 //... other beans
 
 @Bean(initMethod="start",destroyMethod="stop")
 public org.h2.tools.Server h2WebConsonleServer () throws SQLException {
   return org.h2.tools.Server.createWebServer("-web","-webAllowOthers","-webDaemon","-webPort", "8082");
 }
}

The -webDaemon means run H2 web console in a daemon thread which will not block the application process termination. -webPort can set the web console service port, default is 8082. The web console url is http://localhost:8082 (Different from the web console url in spring boot application)

Use H2 in spring boot application

In a spring boot application, first add H2 to the dependency.

  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.182</version>
    <scope>runtime</scope>
  </dependency>

Choose a proper H2 version to use and also set scope to runtime become you should not expliity use any class from H2 in you application.

Then configure application.properties or application.yml file for spring boot datasource. Following is example in application.yml file.

spring:
  datasource:
    url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    username: sa
    password:
    driver-class-name: org.h2.Driver
    platform: h2

  # enable H2 web console and set url for web console
  # http://localhost:8080/console
  h2:
    console:
      enabled: true
      path: /console
The default username for H2 is 'sa', default password is empty.

If you also use spring security in your application, which means spring security is in your pom.xml like below.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Then you need to add a line in your spring security configuration to make H2 web console working.

@EnableWebSecurity
 
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
 
 //......
 
 
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/").permitAll(); 
    http.authorizeRequests().antMatchers("/imgs/**").permitAll(); 
    http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN");
    http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin();
  
    // add this line to use H2 web console
    http.headers().frameOptions().disable();
  }
}

Without this line to setup frame in spring security, you will see a empty page after you login the H2  web console.

Wednesday, December 9, 2015

Most used Hibernate properties during development

Hibernate has many properties that can be very helpful during development phrase. In this article we list some most used hibernate properties  used when developing/testing persistence layer applications.

1. Meaning of most used hibernate properties

1.1 Print out Hibernate created SQL

hibernate.show_sql = true

1.2 Automatic create tables according to entities

hibernate.hbm2ddl.auto = create

Change to create-drop if you want to drop the created table when application over. Useful for prototype and testing.

1.3 Run SQL scripts at beginning of application

hibernate.hbm2ddl.import_files = /path/of/sqlfile

This's most used to insert some test data before unit test case running.

1.4 Use c3p0 connection pool

hibernate.c3p0.min_size=5                              // minimum connections in pool
hibernate.c3p0.max_size=20                           // maximum connections in pool
hibernate.c3p0.timeout=1800                        // time out to remove idle connection. In seconds
hibernate.c3p0.max_statements=50          // cache prepared statements
hibernate.c3p0.idle_test_period=3000      // how often to validate a connection. In seconds.

1.5 Use Improved Naming Strategy ("clientAddress"->"client_address")

hibernate.ejb.naming_strategy  = org.hibernate.cfg.ImprovedNamingStrategy

2. Use Hibernate properties in JPA persistence.xml

If use Hibernate as JPA provider, you can set hibernate properties in persistence.xml.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
  xmlns="http://xmlns.jcp.org/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
                      http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="persistenceUnitName"  transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <!-- common jdbc configuration -->
      <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:mydb" />
      <property name="javax.persistence.jdbc.user" value="sa" />
      <property name="javax.persistence.jdbc.password" value="" />
    
      <!-- ==================== -->
      <!-- hibernate properties -->
      <!-- ==================== -->
      <property name="hibernate.hbm2ddl.auto" value="create" />
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
    </properties>
  </persistence-unit>
</persistence>

3. Use Hibernate properties in Spring Boot


Spring boot does a lot of auto configurations.  So there is no need to use hibernate.hbm2ddl.import_files to set a sql script file location to run. Just put the sql script file as src/main/resources/import.sql. Spring boot will auto config it if spring-boot-starter-data-jpa is in pom.


There is also no need for hibernate.hbm2ddl.auto. Spring boot will also auto detect if the database used is a embedded one, like HSQL, H2 or Derby, or external database. If a embedded database is used,  default is create-drop. Otherwise for external database,  default is none. (No tables will be auto created). You can set this behavior in spring boot's  configuration file application.properties with spring.jpa.hibernate.ddl-auto= create, for example.


Other hibernate properties can be se with prefix 'spring.jpa.properties.' , such as add following lines in /src/main/resources/application.properties 


# hibernate special properties, with prefix "spring.jpa.properties."
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.c3p0.min_size=3
spring.jpa.properties.hibernate.c3p0.max_size=10
spring.jpa.properties.hibernate.show_sql=true

4. What's More


For complete hibernate 4.x configuration properties, check official hibernate reference.

Powered by Blogger.

About The Author

My Photo
Has been a senior software developer, project manager for 10+ years. Dedicate himself to Alcatel-Lucent and China Telecom for delivering software solutions.

Pages

Unordered List