Category Archives: Spring

Spring configuration for a JSON/XML REST service in Java

In Creating a CXF service that responds with JSON or XML and Creating a CXF client which can get JSON or XML we created a service and a client application for interacting with REST requests using XML or JSON as the body for the messages.

The Java guys love spring and beans, my code was all in Java source. So I’m going to show how to convert both the server and client into spring configurations.

In your client/server code add a resources folder to /src/main and within that add a new xml file, named whatever you like, mine’s spring-client.xml and spring-server.xml (for the client and server respectively).

Changes to the server

Let’s concentrate on the server first – our code looked like this

JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean();
factoryBean.setResourceClasses(SampleServiceImpl.class);
factoryBean.setResourceProvider(new SingletonResourceProvider(new SampleServiceImpl()));

Map<Object, Object> extensionMappings = new HashMap<Object, Object>();
extensionMappings.put("xml", MediaType.APPLICATION_XML);
extensionMappings.put("json", MediaType.APPLICATION_JSON);
factoryBean.setExtensionMappings(extensionMappings);

List<Object> providers = new ArrayList<Object>();
providers.add(new JAXBElementProvider());
providers.add(new JacksonJsonProvider());
factoryBean.setProviders(providers);

factoryBean.setAddress("http://localhost:9000/");
Server server = factoryBean.create();

The first thing we need to do is update our pom.xml to import spring, so add the following to the properties section

<spring.version>2.5.6</spring.version>

and then these dependencies

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
</dependency>

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
</dependency>

Now change the Java code in our main method, replacing all the code which is listed above, to

ApplicationContext context = new ClassPathXmlApplicationContext("spring-server.xml");

Now we need to add the following to our spring-server.xml file

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

    <jaxrs:server address="http://localhost:9000">
        <jaxrs:serviceBeans>
            <bean class="SampleServiceImpl" />
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json"/>
            <entry key="xml" value="application/xml"/>
        </jaxrs:extensionMappings>
        <jaxrs:providers>
            <bean class="org.apache.cxf.jaxrs.provider.JAXBElementProvider" />
            <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
        </jaxrs:providers>
    </jaxrs:server>
</beans>

We’re using the jaxrs configuration to create our service beans which means the server is automatically created for us.

That’s it for the server.

Changes to the client

Let’s look at the existing client code

List<Object> providers = new ArrayList<Object>();
providers.add(new JAXBElementProvider());
providers.add(new JacksonJsonProvider());

SampleService service = JAXRSClientFactory.create(
   "http://localhost:9000", SampleService.class, providers);

WebClient.client(service)
   .type(MediaType.APPLICATION_JSON_TYPE)
   .accept(MediaType.APPLICATION_JSON_TYPE);

First off, we need to add spring to the pom.xml as we needed for the server, so duplicate the steps for updating the pom.xml as already outlined.

Next we replace our client code (above) with the following

ApplicationContext context = new ClassPathXmlApplicationContext("spring-client.xml");
SampleService service = (SampleService)context.getBean("client");

and finally put the following into the spring-client.xml file

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

    <jaxrs:client id="client" address="http://localhost:9000" serviceClass="SampleService">
        <jaxrs:providers>
            <bean class="org.apache.cxf.jaxrs.provider.JAXBElementProvider" />
            <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
        </jaxrs:providers>
        <jaxrs:headers>
            <entry key="Accept" value="application/json" />
        </jaxrs:headers>
    </jaxrs:client>
</beans>

and that’s it – run the server, then run the client and all should work.

Note: I’ll leave it to the reader to add the relevant import statements

Using spring annotations

In a previous post I implemented a simple bean and created the SpringBeans configuration file, but spring can also be used with annotations (attributes to us .NET people).

So let’s take the previous posts code and amend it to use annotations.

  • Remove or comment out the contents of SpringBeans.xml
  • Change the HelloWorld bean to look like this
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class HelloWorld {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void output() {
            System.out.println("Bean says " + name);
        }
    }
    
  • Change the main method to look like this
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public static void main( String[] args )
    {
       AnnotationConfigApplicationContext context =
          new AnnotationConfigApplicationContext(IocConfiguration.class);
    
       HelloWorld obj = (HelloWorld) context.getBean("helloBean");
       obj.output();
    }
    
  • We still need a way to define how our beans are going to be created. We’re going to do this via a class, which we’ll name IocConfiguration (the name is unimportant), here’s the class
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class IocConfiguration {
    
        @Bean(name = "helloBean")
        public HelloWorld getHelloWorld() {
            HelloWorld o = new HelloWorld();
            o.setName("Hello World");
            return o;
        }
    }
    
  • Now before you can using the @Configuration you’ll need to update the Maven pom.xml to download cglib, so add the following dependency
        <dependency>
          <groupId>cglib</groupId>
          <artifactId>cglib</artifactId>
          <version>2.2.2</version>
        </dependency>
    
  • Run mvn install and now build and run the application.

Creating a simple spring bean

I’m going to create the standard Hello World spring bean. To start with, let’s use Maven to create a simple “default” set of files and from this we’ll start coding our bean.

To start with, run the following Maven command

mvn archetype:generate -DgroupId=com.putridparrot.core -DartifactId=SpringStarter -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Now open the pom.xml and before the dependencies element add the following

<properties>
   <spring.version>3.0.5.RELEASE</spring.version>
</properties>

and within the dependencies element add the following

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
</dependency>

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
</dependency>

Back to the command line, run (from the folder where your pom.xml is located)

mvn install

This command will run the pom.xml and install the spring framework dependencies.

Let’s add a bean

Beans are simply classes which are managed by the spring framework, so let’s create the obligatory HelloWorld bean

package com.putridparrot.core;

public class HelloWorld {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void output() {
        System.out.println("Bean says " + name);
    }
}

Now we’ll need to change the main method generated by Maven to look like this

ApplicationContext context = 
   new ClassPathXmlApplicationContext(
      "SpringBeans.xml");

HelloWorld obj = (HelloWorld) context.getBean("helloBean");
obj.output();   

You’ll also need the following imports

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

Spring is an IoC container and it will use (in this instance) a configuration file to define the objects (beans) to be created when an identifier (helloBean) is used.

You’ll notice that we’re telling spring to use the SpringBeans.xml file, which we haven’t yet created. In your main folder create a resources folder and within this add create the file SpringBeans.xml. It should look like this

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="helloBean" class="com.putridparrot.core.HelloWorld">
        <property name="name" value="Hello World" />
    </bean>
</beans>

So in the above we create the identifier helloBean, as stated previously, when we ask for an object with this identifier spring will supply a com.putridparrot.core.HelloWorld instance. We also supply a property value which is injected to the setName method (Java doesn’t support properties like C# so name is translated to setName). Thus, the value Hello Worldoutput method to see whether it all worked.