29
Mar
17

JAX-RS Spring based project example


The following page describes how to get a spring context initialized and injected into a rest based project running on JBOSS AS.

Technology Stack

  • JAX-RS
  • Spring
  • JBOSS EAP
Full downloadable source for this page is available here. Corrections and enhancements are welcome, fork, change and push back to GitHub.

Maven Project Configuration

pom.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>com.test</groupId>
    <artifactId>jboss-helloworld-rs</artifactId>
    <version>20170329</version>
    <packaging>war</packaging>

    <pluginRepositories>
      <pluginRepository>
        <id>numberformat-releases</id>
        <url>https://rawgit.com/numberformat/20130213/master/repo</url>
      </pluginRepository>
    </pluginRepositories>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <version.jboss.spec.javaee.7.0>1.0.3.Final-redhat-2</version.jboss.spec.javaee.7.0>

        <!-- other plug-in versions -->
        <version.war.plugin>2.1.1</version.war.plugin>

        <!-- maven-compiler-plugin -->
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Define the version of the JBoss Java EE APIs we want to import.
                Any dependencies from org.jboss.spec will have their version defined by this
                BOM -->
            <!-- JBoss distributes a complete set of Java EE APIs including
                a Bill of Materials (BOM). A BOM specifies the versions of a "stack" (or
                a collection) of artifacts. We use this here so that we always get the correct
                versions of artifacts. Here we use the jboss-javaee-7.0 stack (you can
                read this as the JBoss stack of the Java EE APIs). You can actually
                use this stack with any version of JBoss EAP that implements Java EE. -->
            <dependency>
                <groupId>org.jboss.spec</groupId>
                <artifactId>jboss-javaee-7.0</artifactId>
                <version>${version.jboss.spec.javaee.7.0}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>4.1.4.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>            
        </dependencies>
    </dependencyManagement>

    <dependencies>

        <!-- Import the CDI API, we use provided scope as the API is included in JBoss EAP -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- Import the Common Annotations API (JSR-250), we use provided scope
            as the API is included in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.annotation</groupId>
            <artifactId>jboss-annotations-api_1.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- Import the JAX-RS API, we use provided scope as the API is included in JBoss EAP -->
        <dependency>
            <groupId>org.jboss.spec.javax.ws.rs</groupId>
            <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
            <scope>provided</scope>
        </dependency>
<!-- Spring -->        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>        
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <!-- Set the name of the WAR, used as the context root when the app
            is deployed -->
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>${version.war.plugin}</version>
                <configuration>
               <!-- Java EE doesn't require web.xml, Maven needs to catch up! -->
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>github.numberformat</groupId>
                <artifactId>blog-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <configuration>
                <gitUrl>https://github.com/numberformat/wordpress/tree/master/${project.version}/${project.artifactId}</gitUrl>
                </configuration>
            <executions>
              <execution>
                <id>1</id>
                <phase>site</phase>
                <goals>
                  <goal>generate</goal>
                </goals>
              </execution>
            </executions>
            </plugin>            
        </plugins>
    </build>
</project>

Web Configuration and Html files

src/main/webapp/WEB-INF/web.xml

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <!-- One of the way of activating REST Servises is adding these lines, the server is responsible for adding the corresponding servlet automatically. If the src folder, org.jboss.as.quickstarts.rshelloworld.HelloWorld class has the Annotations to receive REST invocation-->
    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

src/main/webapp/WEB-INF/beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Marker file indicating CDI should be enabled -->
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all">
</beans>

src/main/webapp/index.html

<!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=UTF-8">
<title>helloworld-rs</title>
</head>
<body>

    <p>Choose between <em>JSON</em> or <em>XML</em>:

    <ul>
    	<li><a href="rest/json">JSON</a></li>
        <li><a href="rest/xml">XML</a></li>
    </ul>
</body>
</html>

Java Code

Here we have a spring config via java annotated class.

src/main/java/com/test/SpringConfig.java

package com.test;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * This class replaces the spring xml configuration.
 * 
 */
@Configuration
@ComponentScan("com.test")
@EnableTransactionManagement 
public class SpringConfig {

}

Next we have a context holder class. This is a CDI Bean that will hold a reference to a spring context. This is the only place CDI is used in the project.
src/main/java/com/test/ContextHolder.java

package com.test;

import java.util.Arrays;

import javax.annotation.PostConstruct;
import javax.inject.Singleton;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * A simple CDI service which is able to say hello to someone
 */
@Singleton
public class ContextHolder {

	private AnnotationConfigApplicationContext ctx = null;
	
	@PostConstruct
	void postConstruct() {
        // Initialize the spring framework.
        ctx = new AnnotationConfigApplicationContext();  
        ctx.register(SpringConfig.class);
        ctx.refresh();
		System.out.println("Post construct on service called.");
		System.out.println(Arrays.asList(ctx.getBeanDefinitionNames()));
	}
	
	public ApplicationContext getContext() {
		return ctx;
	}


}

Spring Service Bean
src/main/java/com/test/HelloService.java

package com.test;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    String createHelloMessage(String name) {
        return "Hello " + name + "!";
    }
}

Rest Resource
src/main/java/com/test/HelloWorld.java

package com.test;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

/**
 * A simple REST service which is able to say hello to someone using HelloService Please take a look at the web.xml where JAX-RS
 * is enabled
 */

@Path("/")
public class HelloWorld {
    @Inject
    private ContextHolder contextHolder;
    private HelloService helloService;

    @PostConstruct
    void postConstruct() {
    	System.out.println("PostConstruct called.");
    	helloService = (HelloService) contextHolder.getContext().getBean("helloService");
    }
    
    @GET
    @Path("/json")
    @Produces({ "application/json" })
    public String getHelloWorldJSON() {
        return "{\"result\":\"" + helloService.createHelloMessage("World") + "\"}";
    }

    @GET
    @Path("/xml")
    @Produces({ "application/xml" })
    public String getHelloWorldXML() {
        return "<xml><result>" + helloService.createHelloMessage("World") + "</result></xml>";
    }

}
Full downloadable source for this page is available here.
Advertisements

0 Responses to “JAX-RS Spring based project example”



  1. Leave a Comment

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 77 other followers

March 2017
S M T W T F S
« Mar    
 1234
567891011
12131415161718
19202122232425
262728293031  

Blog Stats

  • 836,405 hits

%d bloggers like this: