I was running gwt application on tomcat server and here is the error I encountered. After fighting with this error for some time I resolved this issue by deleting the jax-impl.jar from the tomcat lib folder. It was a possible conflict of the jaxb jar versions with one of my webapps installed in tomcat. Related ... [Read more...]
I just spent the last few days trying to find an easy way to configure my web services deployed as annotated POJOs and I think I've found it. The idea is to provide an easy mechanism to change values through the administration console and have the java code pick up those changes at run time without redeploying. I thought about using a property file but this is inconvenient because we have a clustered environment and editing files in a deployment directory isn't the best idea.
@Resource Saves the Day
Anybody who used JNDI before the days of annotations knows that old style lookups were a little bit of a pain, but maybe I’m just being difficult. Here’s how I got it working - first thing is to add the proper entries in my web.xml:
...
DsixE/SomeParameter
java.lang.String
This really rocks
...
I build a WAR, deploy it to WebSphere and notice that I have a new entry in the administration console:
…. which allows me to change the value at any time:
Now the container injects the value defined into member variable someParameter at run time. This is the first time I’ve really used an so I guess this old dog can still learn new tricks.
A while ago I discussed how web services can be invoked using javascript in a browser, but there was a nagging problem that prevented me from deploying it into a production environment - how do I prevent a hacker from manipulating the user identifier in a request? Suppose we have an application that displays an end user's payroll information. In this case we need web service operation will retrieve information specific to the user's ID. We can't just send the user's identifier in the request because that would allow spoofing the ID of another person resulting in a breach of privacy.
Retrieving the User's Identity from the Container
In a servlet, it is relatively easy to retrieve the user's identity from the request, but this presents a problem if we're using JAX-WS annotated POJOs which have no concept of HTTP or a request object. How the heck do I figure out what the user ID is? I spent many hours looking at WS-Security but I got lost in all the details about policy sets and bindings and I just couldn't get anything to work. Then I found this writeup on developerworks:
http://www.ibm.com/developerworks/websphere/library/techarticles/1001_chung/1001_chung.html?ca=drs-
It is very close to what I wanted to do, but it uses WS-Security and I was dead in the water. Instead, I fell back on servlet security configuration to get the container to use the SSO LTPA token originating from WebSeal. This is the same way I would handle the situation if I was coding a servlet, but again - I'm working with POJOs, so no request object available. The developerworks article revealed the missing piece:
@Resource WebServiceContext wsCtx;
Putting it all Together
I coded a POJO and added JAX-WS annotations to expose it as a web service, then I added an @Resource that tells the container to pass the context:
package com.dsixe;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
@WebService
public class ContactsService {
@Resource WebServiceContext wsCtx;
public String getName() {
String userID = wsCtx.getUserPrincipal().toString();
if (userID.equals("cdomingue"))
return "Carl";
if (userID.equals("csmith"))
return "Christine";
return "unknown: " + userID;
}
}
Until this point I had never even looked at the web.xml bundled with the annotated POJOs into the WAR that I deployed to Axis2 since there are no servlets in it. I added the following security constraints to the web.xml:
Jax-wsPolicyTest
index.html
ContactsService
/*
Roles allowed to execute ContactsService
AllAuthenticatedUsers
All Authenticated Users Role
AllAuthenticatedUsers
I then deployed to the container and mapped the AllAuthenticatedUsers security role just like I would for any servlet. Protecting the resource caused the container to populate the WebServiceContext object and then I could retrieve the user ID.
Done!
EDIT: I was researching attachments with JAX-WS and found this very comprehensive writeup which I though would be good to read in this context.
EDIT: Here's another interesting read on this topic.
Exploring Web Services - Writing Your First Web Service
In this tutorial I will explain how to implement a simple web service and client using The Java API for XML Web Services (JAX-WS)
JAX-WS communication between a web service and client
As the first step of developing a JAX-WS web service, we have to implement a Java class annotated with the javax.jws.WebService annotation. The @WebService annotation defines the class as a web service endpoint. We can also define a Service Endpoint Interface (SEI) which declares the service methods.
Creating JAX-WS Service Endpoint Interface.
package com.wsexample.service; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface HelloWorld { @WebMethod public String sayHello(String name); }
Creating JAX-WS Service Endpoint implementation class
package com.wsexample.service; import javax.jws.WebService; @WebService(endpointInterface = "com.wsexample.service.HelloWorld") public class HelloWorldImpl { public String sayHello(String name) { return "Hello " + name; } }
When creating the implementation class, you have to specify SEI by adding the endpointInterface element to the @WebService annotation in the implementation class.
Creating Endpoint Publisher
The endpoint publisher will publish the service in the specified URL.
package com.wsexample.service; import javax.xml.ws.Endpoint; public class HelloWorldWSPublisher { public static void main(String[] args) { Endpoint.publish("http://localhost:8888/WS/HelloWorld",new HelloWorldImpl()); } }
You can test the service WSDL by running the publisher and type the following URL in a web browser.
http://localhost:8888/WS/HelloWorld?wsdl
Next step would be to create a client to talk to the web service. Before that we need to generate the client stubs. You need to run the following command in the terminal to generate stubs.
Jboss does have their own web service implementation which is JBossWS-CXF, based out of Apache CXF. But if you are into JAX-WS metro stack you can simply use it with jboss.
1. Overide the class loader to load SUN Metro stack instead jboss supplied jax-ws version.
create "jboss-web.xml" file in "WEB-INF" folder with following content.