Tag Archives: spring mvc

JAX-WS Client: Consuming the JAX-WS webservice!

In this post we’ll see how to write a client to consume the JAX-WS webservices. This client will invoke the methods of a remote webservice. For this we’ll utilize the already created JAX-WS webservice in this post.

Since, it’s the era of webapps, our client too will be powered by Spring MVC! We can make the client in two ways, and each is simpler than the other!

Download the Client’s Source Code!

PizzaStory
This is what we’re here to do! Order Pizza! 🙂

This picture pretty much sums up the design, architecture and structure of this Producer-Consumer code!

Let’s start!

1. Download and import the PizzaService first, and get it up and running. Confirm by seeing the wsdl file at this location:

http://localhost:8080/webservice-jaxws/PizzaService?wsdl

2. Generate the artifacts using the wsimport tool. This tool will generate the required classes for you from the wsdl file. These artifacts are necessary, because now your client doesn’t know what a Pizza object looks like, and it doesn’t know which methods he can call on the remote webservice, let alone the location of it!

3. Open the command prompt and type in the following command to generate the artifacts.  Before running the command, create two folders “src” and “gen” to have the source and class files generated at different locations.

wsimport -s src -d gen http://localhost:8080/webservice-jaxws/PizzaService?wsdl

The command and its explanation!
The command and its explanation!

The directory structure to be followed is as follows:-

dir

4. Go in the “src” directory, and see the generated artifacts for yourself! I’ve included a screen-shot too! I’m so dilligent 🙂

The prized artifacts!
The prized artifacts!

5. The next thing is to copy these in your client application. I’ve written a small Spring MVC project for this purpose, and included the above classes in it. It’s hosted on Google codes and you can download it!

6. Sending the request via Ajax! We’ll write this piece of code in the form.jsp page, and on click of a button, this ajax request would be sent to the controller which in turn would call the webservices!


<script type="text/javascript">
 $(function() {

$('#invokeWebservice').click(function() {

//Sending the Ajax request, to call the JAX-WS service.
 $.ajax({
 url : '<%=request.getContextPath()%>/invokeWebservice',
 dataType: 'json',
 success: function(data){

//Setting the data in the page, for viewing!
 $('#pizzaSize').html(data.size);
 $('#pizzaCost').html(data.cost);
 $('#pizzaDateOfManufacture').html(data.dateOfManufacture);
 }
 });
 });
 });
</script>

7. Invoking the webservice can be done in two ways:-

a) Using the generated proxy classes by wsimport tool.

This is the controller. The other parts have been omitted for brevity, and only the code concerned with invoking the webservice is shown here. You can see the complete code by downloading the project! Don’t fret! 🙂

@Controller
@RequestMapping("/")
public class ClientController {

 //This gives us a proxy to the remote webservice.
 //Now call the methods on local "pizzaProxy"
 //and the remote ones will be called automatically!
 private PizzaServiceImpl pizzaProxy = new PizzaService().getPizzaPort();

//This handler will be invoked on the Ajax request.
 @RequestMapping("/invokeWebservice")
 public @ResponseBody Pizza getPizza() {
 //The webservice is being invoked by "pizzaProxy"
 //This method returns a Pizza object.
 return pizzaProxy.getPizza();
 }

}

b) Using Spring’s JaxWsPortProxyFactoryBean

For using the JaxWsPortProxyFactoryBean, you need to configure this in the Spring’s WebApplicationContext file.

<bean id="pizzaProxy" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
 <property name="serviceInterface" value="webservice.jaxws.generated.PizzaServiceImpl"/>
 <property name="wsdlDocumentUrl" value="http://localhost:8080/webservice-jaxws/PizzaService?wsdl"/>
 <property name="namespaceUri" value="generated.jaxws.webservice"/>
 <property name="serviceName" value="PizzaService"/>
 <property name="portName" value="PizzaPort"/>
 </bean>

Then autowire this in the Controller!

@Autowired
 @Qualifier("pizzaProxy")
 private PizzaServiceImpl pizzaProxy;

The directory structure of the client project is as shown below:-
projstructure
Run the the client and you’ll see the following screens.
screen1Click the button to invoke the webservice. And you’ll see the response!
screen2
That’s all for this one! Happy consuming 🙂

Binding date in Spring!

Almost often, we have a situation that a Date field is a part of our domain object. And we rely on Spring for binding this domain object with the view so as to minimize the hassles of dealing with the fields individually, and then setting them in the object in controller.

Let’s suppose we have a domain entity, Book, which has some customary fields (along with the dreaded field Date too) shown in the form below.

So lets now try our luck filling this form. So, there we go.

But, binding date isn’t that straightforward. If you ever tried to bind the date, you must have inevitably got the following error message:

Failed to convert property value of type java.lang.String to required type java.util.Date for property date; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property date: no matching editors or conversion strategy found

And even if you by passed the bean validation, your Controller would return a null for the corresponding date field.

Well, there are two easy solutions.

First: Very Easy Solution

This doesn’t asks you to do anything in your code, but limits your input to a date, whose separators should only and only be ‘/’. E.g. dd/MM/yyyy , yyyy/MM/dd, yyyy/MMM/dd

So, now filling the above information by using “/” as separators and submitting the page.

So this was the first solution.

Second: Easy Solution (Using InitBinder)

This method gives you the freedom, to get your date input in whichever format you like, and with whatsoever separators you desire.

All you need to do is to place this code-snippet in your Controller.


@InitBinder
public void initBinder(WebDataBinder webDataBinder) {
 SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
 dateFormat.setLenient(false);
 webDataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
 }

With this you specify to the Container that you’ll be inputting the date in this very format, and he will do the rest for you.

Let’s try a very bizarre format, dd==MMM==yyyy

To accommodate this above format, change the format declared in InitBinder,


@InitBinder
public void initBinder(WebDataBinder webDataBinder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd==MM==yyyy");
dateFormat.setLenient(false);
webDataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}

Filling in the form with our new date format.

Lets see if it passes the litmus test on submitting the page.

Bingo it did! And all we did was to change the format in Controller, so you can set any format and be assured, you won’t get any ugly surprises(exceptions!).

Download Source Code

You can download the source code from here