Author Archives: purpleblob

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

Benchmarking code in Go

To create a unit test in Go<, we simple create a function with Test as the first part of the name, see my previous post on Unit testing in Go.

We can also write performance/benchmarking test code by creating a function with Benchmark as the first part of the function name, i.e. BenchmarkDataRead and it takes on the same format as a unit test, for example

func BenchmarkEcho(b *testing.B) {
	expected := "Hello"
	actual := test.Echo("Hello")

	if actual == expected {
		b.Error("Test failed")
	}
}

Our benchmark is passed a testing.B type which gives us functionality as per testing.T, in that we can fail a benchmark test etc. Obviously, for a benchmarking type, we also have the ability to start and stop the timer, for example if we have initialization and cleanup code we might want to exclude these from the benchmark by just wrapping the key code in a b.StartTimer and b.StopTimer section, i.e.

func BenchmarkEcho(b *testing.B) {
	expected := "Hello"

	b.StartTimer()
	actual := test.Echo("Hello")
	b.StopTimer()

	if actual != expected {
		b.Error("Test failed")
	}
}

Unit tests in Go

In the previous post I mentioned that the Go SDK often has unit tests alongside the package code. So what do we need to do to write unit tests in Go.

Let’s assume we have the package (from the previous post)

package test

func Echo(s string) string {
	return s
}

assuming the previous code is in file test.go and we then create a new file in the same package/folder named test_test.go (I know the name’s not great).

Let’s look at the code within this file

package test_test

import "testing"
import "Test1/test"

func TestEcho(t *testing.T) {
	expected := "Hello"
	actual := test.Echo("Hello")

	if actual != expected {
		t.Error("Test failed")
	}
}

So Go’s unit testing functionality comes in the package “testing” and our tests must start with the word Test and takes a pointer to type T. T gives us the methods to create failures etc.

In Gogland you can select the test_test.go file, right mouse click and you’ll see the Run, Debug and Run with coverage options.

Creating your own package in Go

When we import a library in Go we’re really importing a package. A package is created in a folder of it’s own and whilst you can name the folder anything you like, by convention we should name the folder the same as the package name that the files within the folder will be part of.

For example if our project is in the folder src/example and we want to create a package called conv (for converters) then this should be created in src/example/conv.

The files within this folder can be named anything you like and can have any package names, for example the Go source has a package context and it includes files as part of the package context but also package context_test, but ofcourse it makes sense that the code is all relevant to the package/folder it’s contained within – for example tests etc. might have a different package name to not pollute the package that the user/dev sees.

Let’s create a simple Echo function in a package named test, so off of our main.go folder we create a test folder and within this we have a test.go file and here’s the source

package test

func Echo(s string) string {
	return s
}

to use this package in our main.go file we import like this

package main

import "fmt"
import "Example/test"

func main() {
	fmt.Println(test.Echo("Hello"))
}

Notice the Example/test (our project name in Gogland) followed by the package folder name. The Example folder in this case is the folder that our main.go file is within.

References

How to Write Go Code contains a great overview of project, folder and package layouts for your Go application.

Interfaces and duck typing in Go

Go isn’t object oriented in the typical sense, i.e. if you’re coming from C#, Java or even C++, but it does offer some features which map to features often available in the OO world in one way or another.

For example in a previous post we saw how we created methods that mirror the syntax of methods on objects (or extension methods in C#). We also have interfaces in Go which can include functions.

For example

type Duck interface {
   Quacks()
}

But how do we implement an interface as we cannot include functions in types?

So with our knowledge of methods we will see how we can implement a type that conforms to an interface. As we are not “implementing” or otherwise inheriting from an interface we instead duck type the interface.

Duck typing comes from the phrase – if something looks like a duck, swims like a duck and quacks like a duck then it’s probably a duck.

In programming terms duck typing is the matching of types based upon expected methods and properties rather than upon an expected type. Therefore our Duck interface can be implemented by objects which don’t even need to know about the Duck interface.

For example

type Animal struct {
}

func (a Animal) Quacks() {
   fmt.Println("The animal quacks");
}

function Quack(duck Duck) {
   duck.Quacks()
}

func main() {
   a := Animal{}
   Quack(a)
}

So in the above we’ve declare an Animal type and create a method for the Animal type which is named Quacks (thus fulfilling the requirements of the Duck interface).

Next we have a function which takes a Duck and calls the Quack method on it.

But as you see within main, we’re actually able to pass an Animal type into the function which resolves to Duck because it supports the required interface. Hence duck typing.

Functions and Methods in Go

In the previous post on Go I’ve used the words method and function interchangeably, but as I learn more about Go I find that – in Go, methods and functions are actually different.

First off, let me point you to this post Part 17: Methods which covers this subject in more depth. But here’s the elevator pitch.

Methods names can be overloaded and the syntax of using a method is more like a method on an object.

Let’s look at a simple example, a classic sort of OO example. We have different shape types and each has an area method.

This is example is taken from Part 17: Methods

type Rectangle struct {
   length float64
   width float64
}

type Circle struct {
   radius float64
}

func (shape Rectangle) Area() float64 {
   return shape.length * shape.width
}

func (shape Circle) Area() float64 {
   return math.Pi * math.Pow(shape.radius, 2)
}

Notice that a method has the type declared before the method name (unlike a function) and this is because we call it in the way we would an extension method and object’s method in C#.

In Go the type declared after the function name (function syntax) is known as an argument, whereas a type declared before the function name (method syntax) is known as a receiver.

For example

r := Rectangle{ length = 100, width = 23 }
c := Circle { radius = 30 }

rArea := r.Area()
cArea := c.Area()

Starting out with Go

I like learning different programming languages. Sometime I learn alternate ways to do things which might be useful in my usual language, sometimes I get a feel for how another language might be better for certain tasks and gives me more options for developing apps. I recently started learning the language Go, so this is my first of several posts on what I’ve learned.

Note: I’m literally just learning this, so I suspect any posts on the subject will be pretty basic, but hopefully, might be of use to others (as well as myself).

Why Go?

Probably the first question many of us might ask is why pick a specific language. For example, is the language all about speed, or writing application in a specific paradigm like a functional language.

So Why Go? Where does it fit into?

Before we look to answer that question, we should note that Go was designed by Google as an open source, compiled and statically typed language.

So we might view Go as a possibly modern take on C but with features, such as concurrency as primitives as well as being a garbage collected language. It’s cross platform and compiles to native. The language is a general purpose language, so it can do many things, but I’ve not found anything to suggest it’s aimed at GUI work. I’ve seen lots of talk about supporting distributed code, and services/microservices etc. but not yet done anything with these, so cannot confirm how good it is as such things.

Let’s get started and download Go

Okay, so you can read a brief history of Go from Wikipedia etc., let’s instead download Go and install it from Downloads.

On Windows (as I’m currently running it) by default the installation is into C:\Go and this is what the environment variable %GOROOT% should be set to (either during installation or manually assigned if need be).

You’ll need to set up the %GOPATH% environment variable (or via your preferred IDE, I’m using JetBrains Gogland (1.0 Preview)) to point to your workspace, i.e. where you’ll be writing your application(s) to. So, for example, C:\Development\GoglandProjects on my installation is where I’m writing my Go projects to at the moment.

Note: You do seem to be able to get away without a GOPATH.

Hello World

Yes, this one’s on The Go Programming Language website, but we’ll recreate here.

  • In your workspace create a HelloWorld folder
  • Create the file hello-world.go in your preferred editor
  • Type into the file, the following
    package main
    
    import "fmt"
    
    func main() {
       fmt.Println("Hello World")
    }
    
  • From a command prompt (within the workspace\HelloWorld folder) run
    go build hello-world.go
    

    or even simpler (if you’re in the code’s folder), just run

    go build
    

    This command compiled the Go code into a native EXE

At this point you’ll have a binary (hello-world.exe) that you can run or if you delete this and run the following line from the command prompt in your workspace

go run hello-world.go

then Go will compiled to a temporary EXE, i.e. no EXE is create in our workspace, it just runs the go code.

In the hello-world.go code, you’ll see standard looking constructs, for example we have an include/import/using type line which imports the fmt package, you have a func main, which is obviously a function/method (and should be in a package named main) and some call on the fmt package which ouputs to the console the string “Hello World”.

So all pretty recognisable.

Note: I mentioned fmt is a package and at first site this appears to be like an object/class, but Go is not an object oriented language. There’s no inheritance for example, or base object but there are constructs that can give us some OO like capabilities, instead of objects we have structures “struct” types like in C as well as interfaces.

Basics

Here’s a quick list of some of the basics we expect to see in a language.

Commenting

The standard C++ // and /* */ operators are used for single line and multi line comments respectively.

Namespace/Package

Analogous to a namespace, we have the package – for example

package fmt

Creating your own types

As mentioned, Go is not an OO language, but like C with typedef and struct we can create our own custom types, for example

type MyInteger int

or a struct using

type MyStructure struct {
	a MyInteger
	b MyInteger
}

Declaring variables

We define variables using the var keyword (like the optional usage in C#), i.e.

var myInteger = 3

In the case of situations where we want to declare the type. We declare the type after the variable name, i.e.

var myInteger MyInteger = 3

We could also use

var myInteger = MyInteger(3)

Note: Interestingly, declaring an unused variable results in a compile time error as does unused packages, this ensure you keep your code “clean” of anything not required.

Basic types

Ofcourse Go includes the basic types (see builtin.go) which include string, int, unit, byte, float, bool etc.

Loops

Ofcourse we for loops (see below), but interestingly no while loops

for i := 0; i < 3; i++ {
   fmt.Println("Hello")
}

with the := reminds me of a Pascal crossed with C style. Notice no parenthesis are required around the for loop but braces are required.

Also parenthesis must be placed (opening parenthesis {) on the same line as the loop (of if statements).

Using a for loop like a while loop just means writing the following

i := 0
for i < 3 {
   fmt.Println("Hello")
   i++
}

A while(true) infinite loop can be written as

for {
   fmt.Println("Hello")
}

Flow control with if..else and switch statements

if i % 2 > 0 {
   fmt.Println(strconv.Itoa(i) + " Odd")
}

We can also declare/assign variables as part of the if statement, for example

if isOdd := i % 2; isOdd > 0 {
   fmt.Println(strconv.Itoa(i) + " Odd")
}

else statements must be on the closing brace line and their opening brace on the same line also, for example

if isOdd := i % 2; isOdd > 0 {
   fmt.Println(strconv.Itoa(i) + " Odd")
} else {
   fmt.Println(strconv.Itoa(i) + " Even")
}

Switch statements are pretty much as per C# etc.

switch i % 2 {
case 0:
   fmt.Println(strconv.Itoa(i) + " Odd")
default:
   fmt.Println(strconv.Itoa(i) + " Even")
}

like if statements, we can also assign variables and test them after the switch keyword and before the opening brace.

Functions

As mentioned already, we create functions using the func keyword. Functions can take arguments and return values (as you’d expect). For example

func isOdd(i int) bool {
	return i % 2 != 0
}

Note: we declare the return type after the function (or no type for the equivalent of a void function) and we use the return keyword as per many C like languages.

We can pass multiple arguments into a function in the standard way

func doSomething(i int, test bool) bool {
// do something
}

we can also group arguments of the same type like so

func doSomething(a, b, c int) bool {
// do something
}

We’ve shown code returning a single value, but we can also return tuples easily using the following syntax

func doSomething() (string, string) {
	return "Hello", "World"
}

and assigning this we would have something like

a, b := doSomething()

We can create anonymous functions using the func() syntax, for example

func doSomething() func() string {
	return func() string {
		return "Hello World"
	}
}

will return a function which returns a string.

We can also pass variable arguments to a function (like vargs or params) using

func doSomething(args ...string) {
	for _, arg := range args {
		fmt.Println(arg)
	}
}

Note: in this example the _ is used as range returns a tuple of index (int) and the value (i.e. value[index]), The _ can be used in situations where we want to ignore a value and is special in that it will not cause an unused variable compile time error.

Anonymous and named returns

In the above we looked at declaring return values like this

func doSomething() (string, string) {
	return "Hello", "World"
}

in that the return (string, string) has no variable name associated with it, but we can also return named variables, for example

func doSomething() (a string, b string) {
	return "Hello", "World"
}

at this point the named returns only really demonstrate a use as a form of documentation, but they also get automatically initialized to the defaults for the type and can be used in a similar way to the out keyword in C#, i.e. we can assign to them.

Here’s an example

func doSomething() (a string, b string) {
	a = "Hello"
	b = "World"
	return
}

so here we assign the named return a value and then we must still use a return. This allows us to build up the return tuple during the flow of the function, instead of storing as a local variable until we return the tuple.

Arrays

Let’s end this post with arrays. The standard [] syntax is used, here we declare an array and initialize it

a := [2]string{"Hello", "World"}

arrays are base 0 index, hence

fmt.Println(a[0]) 

will result in Hello output to the console.

Package visibility

Functions and methods with a capitalized first letter (i.e. Pascal case) are public, whereas a lowercase first letter (i.e. Camel case) are private to the package.

In other words the public functions are visible globally whereas private are visible only within the package.

References

The Go Programming Language
Go by example

Building a REST service with Spring

I’ve been doing a fair bit with SOAP, REST and Java recently using CXF. A previous post demonstrated using CXF/JAXB to create a REST style service that returned either JSON or XML, let’s look at using Spring REST services to implement the same functionality.

Let’s start (as usual) with our pom.xml

<?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>org.springframework</groupId>
    <artifactId>sample-rest-service</artifactId>
    <version>0.1.0</version>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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


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

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

Now we create our folder structure, so create the following from the root folder

src/main/java/demo

We’re going to need to code within the demo package.

Without the package you might see a warning “Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.”

Next up, we’ll create a service, or in Spring parlance, the controller

package demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {

    @RequestMapping("/purchaseOrder")
    public PurchaseOrderType getPurchaseOrder() {
        return new PurchaseOrderType(1234);
    }
}

The PurchaseOrderType is simply the following

package demo;

public class PurchaseOrderType {

    private long _id;

    public PurchaseOrderType(long id) {
        _id = id;
    }

    public long getId() {
        return _id;
    }
}

Now we need the application to start the service

package demo;

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

@SpringBootApplication
public class Application {

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

To run this we can, ofcourse, set up a configuration or from the Terminal window run

mvn spring-boot:run

Now, if we navigate to http://localhost:8080/purchaseOrder/ we should see

{"id":1234}

Now, let’s extend this to allow us to return XML. We’ll need to annotate PurchaseOrderType with the @XmlRootElement, we’ll also need a default constructor and a setter for our Id property

package demo;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class PurchaseOrderType {

    private long _id;

    public PurchaseOrderType() {
    }

    public PurchaseOrderType(long id) {
        _id = id;
    }

    public long getId() {
        return _id;
    }

    public void setId(long id) {
        _id = id;
    }
}

Changing the port of the Tomcat server

You may have noticed that when running this application we get an instance of a Tomcat server running, by default it uses port 8080, but what about if we need/want to change this. We can create an EmbeddedServletContainerCustomizer, as below.

package demo;

import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContainer implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
        configurableEmbeddedServletContainer.setPort(8888);
    }
}

Code is available here https://github.com/putridparrot/blog-projects/tree/master/spring-rest

Creating a CXF client which can get JSON or XML

In the previous post we created a server which serves up JSON or XML via a REST style interface and whilst we also demonstrated calling it from a browser, we really now need to look at implementing a compatible client.

POM first

Create a pom.xml and copy the following into it (within your client project folder)

<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.putridparrot.client</groupId>
    <artifactId>ppclient</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>ppclient</name>
    <url>http://maven.apache.org</url>

    <properties>
        <cxf.version>2.7.18</cxf.version>
        <httpclient.version>4.3.6</httpclient.version>
        <surefire.version>2.19.1</surefire.version>
        <jackson.version>1.9.13</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>
</project>

Now we create our folder structure, so create the following from the root folder

src/main/java

Select the java folder in IntelliJ and Mark Directory As Sources Root.

We also need to copy the previously generated Java files (via XJC) into our java folder.

Now we’re going to use a proxy to access our service, but we’ll still need a representation of the service. This is another good reason why we separated the interface for the service from the implementation, so copy the interface from the server into our java folder (here’s the code)


import com.putridparrot.sample.PurchaseOrderType;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;

@Path("service")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public interface SampleService {
    @GET
    @Path("purchaseOrder")
    public PurchaseOrderType getPurchaseOrder();
}

Nothing new here, so let’s move onto the actual client code. Add a new class, mine’s ClientApplication and it’s listed below

import com.putridparrot.sample.PurchaseOrderType;
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ClientApplication {
    public static void main(String[] args) throws IOException {

        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_XML_TYPE)
           .accept(MediaType.APPLICATION_XML_TYPE);

        PurchaseOrderType request = service.getPurchaseOrder();

        System.out.println(request.getBillTo().getName());
        System.in.read();
    }
}

Now, in the above we’re again supplying providers for the different types, but this is solely for us to test switching between them, if you’re solely interested in XML then remove the providers, but you’ll still need to specify XML as the accept type.

To switch to JSON as the type returned, we simply switch replace the WebClient code with

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

Ofcourse, in reality we don’t care too much about the format of the message returned when using it with a proxy unless we’re constrained by the server.

Creating a CXF service that responds with JSON or XML

In the first post of the three, we generated the source code from an XSD, now we’re going to create a CXF service that will be able to handle responses in either JSON or XML.

Note: Unlike a previous post on CXF services, this is not a SOAP webservice but is a REST webservice which can respond in the two formats (JSON or XML)

Show me the POM

Here’s the POM (save it as pom.xml in your project’s folder if you’re following along with this post).

<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.putridparrot.server</groupId>
    <artifactId>ppserver</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>ppserver</name>
    <url>http://maven.apache.org</url>

    <properties>
        <cxf.version>2.7.18</cxf.version>
        <httpclient.version>4.3.6</httpclient.version>
        <surefire.version>2.19.1</surefire.version>
        <jackson.version>1.9.13</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>
</project>

Setting up the project

If using IntelliJ, select File | Open, navigate to the pom and open it, you’ll be prompted to open in different ways – Open as Project and then IntelliJ will generate a new project around it.

Use the IntelliJ Terminal window to run

mvn install

We now need to create the standard folder structure, so off of the top level tree node in the project explorer create the following folders

src/main/java

In the project explorer select the java folder and right mouse click on it, select Mark Directory As and then Sources Root.

Now copy the folders generated by XJC (in the previous post) into the java folder.

Implement the server code

It’s preferable to separate the interface (which we’ll need for our client) from the implementation of our service, so create a SampleService interface in the java folder that looks like this

import com.putridparrot.sample.PurchaseOrderType;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("service")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public interface SampleService {
    @GET
    @Path("purchaseOrder")
    public PurchaseOrderType getPurchaseOrder();
}

Notice we’ve marked the interface as producing either JSON or XML.

We’ve set the path to our services as /service and the getPurchaseOrder method as purchaseOrder (we’ve also marked this method as a GET method) so to access we’ll simply append /service/purchaseOrder to our server’s URL.

Now let’s create the implementation, so add a file to the java folder named SampleServiceImpl and it should look like this

import com.putridparrot.sample.PurchaseOrderType;
import com.putridparrot.sample.USAddress;

public class SampleServiceImpl implements SampleService{
    public PurchaseOrderType getPurchaseOrder() {
        PurchaseOrderType po = new PurchaseOrderType();

        USAddress address = new USAddress();
        address.setCity("New York");
        address.setCountry("USA");
        address.setName("SpongeBob");

        po.setBillTo(address);

        return po;
    }
}

Obviously this isn’t useful, but it’s good enough to demonstrate how things fit together.

Finally we’re going to create a server to run this service, so create a new file in the java folder named SampleServer.java and put the following code into it.

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SampleServer {
    public static void main(String args[]) throws Exception {
        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();

        System.out.println("Server ready...");

        System.in.read();

        server.destroy();
        System.exit(0);
    }
}

Now if you run this server up and using your preferred browser access http://localhost:9000/service/purchaseOrder you’ll find an error

JAXBException occurred : unable to marshal type “com.putridparrot.sample.PurchaseOrderType” as an element because it is missing an @XmlRootElement annotation. unable to marshal type “com.putridparrot.sample.PurchaseOrderType” as an element because it is missing an @XmlRootElement annotation.

As can be seen, JAXB expects an XmlRootElement and our generated code does not have one. This is why XJC generated more files than types in the XSD. You may have noticed ObjectFactory. Well without an XmlRoot we need to handle things slightly differently and this is where the ObjectFactory comes in – but for this example (and frankly because it’s ultimately simpler) we’ll add XmlRoot to the PurchaseOrderType ourselves, so it should now look like this

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PurchaseOrderType", propOrder = {
    "shipTo",
    "billTo"
})
public class PurchaseOrderType {
// rest of the code
}

Now if we run the server and again use our browser to access http://localhost:9000/service/purchaseOrder you should see the following

<PurchaseOrder xmlns="http://tempuri.org/PurchaseOrderSchema.xsd">
   <BillTo country="USA">
      <name>SpongeBob</name>
      <city>New York</city>
   </BillTo>
</PurchaseOrder>

Now I mentioned this server should be able to return both JSON or XML. In this case our browser accepts application/xml and hence that’s what’s returned. We can use a chrome application such as ARC and add accept: application/json to return the JSON for the same request, her’s what’s returned

{
"shipTo": [],
"billTo": {
"name": "SpongeBob",
"street": null,
"city": "New York",
"state": null,
"zip": null,
"country": "USA"
},
"orderDate": null
}

Wait, what just happened?

We’ve jumped ahead a little and not described the server. So let’s backtrack a little. In the server we’re creating a JAXRSServerFactoryBean and creating a singleton of the SampleServiceImpl which will be used to handle service requests, but then we do the following

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

Here we’re telling the factoryBean that we can handle these specific extension types and mapping them, but we need to have providers which actually do the work for us, so then we add the following

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

The JAXBElementProvider handles the XML whilst the JacksonJsonProvider (as I’m sure you guessed) handles the JSON. Basically these will generate the message body for our responses etc.

Finally in the main method we create a server from our bean for the given address.