mvn archetype:create -DgroupId=package.name -DartifactId=project_name -Dpackage=package.name.project_name -Dversion=1.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-webapp
As I am using glassfish v 3.1.1 as application server and java 1.6 following pom file is used:
<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>com.sjd.simple</groupId>
<artifactId>SoapService</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<distribution>repo</distribution>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jaxws.plugin.version>2.1</jaxws.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.2-b06</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- Set the name of the war, used as the context root when the app is
deployed -->
<finalName>SoapService</finalName>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<!-- Java EE 6 doesn't require web.xml, Maven needs to catch up! -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- Compiler plugin enforces Java 1.6 compatibility and activates annotation
processors -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Using annotations, the actual implementation of the WebService is very straight forward. Just add an @WebService annotation to your class. If you want to implement an interceptor you just have to use the annotations @Interceptor and specify the class which should be used. Also we will have to annotate our class as java bean.@Stateless
marks this bean as a Stateless Session Bean, and @WebService
causes the application server to make all public methods of this bean accessible as web service calls. Here the interceptor is used for every method insiede our WebService class (You may also use this annotation for individual methods).
package com.sjd.simple;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.jws.WebMethod;
import javax.jws.WebService;
@Stateless
@WebService
@Interceptors( { AuthenticationInterceptor.class } )
public class HelloWorld implements IHelloWorld {
public HelloWorld() {
// nothing to do
}
@Override
@WebMethod
public String sayHello(String bla) {
return "Hello !";
}
}
For the interceptor you will have to write a normal POJO class, but add the annotation @AroundInvoke to a method. This annotation may be applied to any non-final, non-static method with a single
parameter of type InvocationContext
and
return type Object
of the target class/superclass or of any interceptor class. The annotated method will be called before each method that uses this class as interceptor.package com.sjd.simple;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
public class AuthenticationInterceptor {
@AroundInvoke
public Object invoke(final InvocationContext ctx) throws Exception {
if (ctx != null) {
System.out.println("test");
return ctx.proceed();
} else {
return null;
}
}
}
As you can see, implementing a @WebService using an interceptor is fairly easy - but be careful since the interceptor will only work if following requirements are met:
javax.interceptor.Interceptors may be bound to a simple Web Bean, enterprise Web Bean or EJB 3 style session, singleton or message driven bean using the javax.interceptor.Interceptors annotation, or by using a Web Beans interceptor binding. - docs.jBoss
In this case we are using beans as @WebServices, it seems that the URL used to access it changes from:
http://localhost:8080/<application_name>/<class_name>Service?wsdl to
http://localhost:8080/<class_name>Service/<class_name>?wsdl
example:http://localhost:8080/SoapService/HelloWorldService?wsdl [without @Stateless]
http://localhost:8080/HelloWorldService/HelloWorld?wsdl [with @Stateless]
I only figured that one out because of this report: @WebService and @Stateless not showing endpoint in GlassFish 4.0 admin consoleOf course you may change this default URL by the serviceName and name attribute of the @WebService annotation: e.g., @WebService(serviceName="soap", name="testservice"), which would result in following URL to access our webservice:
http://localhost:8080/soap/testservice?wsdl
I hope I could provide some help on how to implement a webservice, while using interceptors. Also here is another link to a nice much more detailed tutorial on WebServices in general.