SOAP Web Service is standard way to integrate your application with other applications. Wildfly is base on Java EE, so it is provide seamless platform to build SOAP Web Service on JAX-WS specification. Create SOAP web service is very simple, at least you need only just on one annotation to convert simple POJO to web service. you can follow step below steps to create web service. The server and client communicate with each other via XML over SOAP (Simple Object Access Protocol) message. A client sends XML SOAP message to server. After processing the request, server send back response to client via XML SOAP message. Request and response XML is defined by WDSL. On this post, I show how to create SOAP Web Service and secure the web service.
Create JAX-WS web service
First is to just create Dynamic Web Project by using eclipse.Create Dynamic Web Project |
select Run time environment |
config folder |
Finish |
Create package |
Create Interface |
Import JPA Project |
Import EJB Project |
Finish import related project |
package com.jaxws.webservice;
import java.util.List;
import com.jpa.model.User;
public interface UserCrud {
public void save(User user);
public List<User> getUsers();
}
Then you can create class that implement UserCrud interfaceimport java.util.List;
import com.jpa.model.User;
public interface UserCrud {
public void save(User user);
public List<User> getUsers();
}
package com.jaxws.webservice;
import java.util.List;
import javax.ejb.EJB;
import com.ejb.crud.UserEjb;
import com.jpa.model.User;
public class UserCrudImp implements UserCrud {
@EJB
private UserEjb userEjb;
@Override
public void save(User user) {
userEjb.save(user);
}
@Override
public List<User> getUsers() {
return userEjb.getUsers();
}
}
Now Convert your simple class to web service by add annotation to your interface and the interface implement class. First, we will add annotation to the interface.import java.util.List;
import javax.ejb.EJB;
import com.ejb.crud.UserEjb;
import com.jpa.model.User;
public class UserCrudImp implements UserCrud {
@EJB
private UserEjb userEjb;
@Override
public void save(User user) {
userEjb.save(user);
}
@Override
public List<User> getUsers() {
return userEjb.getUsers();
}
}
package com.jaxws.webservice;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import com.jpa.model.User;
@WebService(name="userCrud",
targetNamespace="https://wildfly.itstikk.pro"
)
@SOAPBinding(style=Style.DOCUMENT)
public interface UserCrud {
@WebMethod(action="save",operationName="saveUser")@WebResult(name="saveResult")
public void save(@WebParam(name="userParam") User user);
@WebMethod(action="get",operationName="getUser")
@WebResult(name="user")
public List<User> getUsers();
}
package com.jaxws.webservice;
import java.util.List;
import javax.ejb.EJB;
import javax.jws.WebService;
import com.ejb.crud.UserEjb;
import com.jpa.model.User;
@WebService(endpointInterface="com.web.service.UserCrud",
portName="userCrudPort",
serviceName="userCrudService"
)
public class UserCrudImp implements UserCrud {
@EJB
private UserEjb userEjb;
@Override
public void save(User user) {
userEjb.save(user);
}
@Override
public List<User> getUsers() {
return userEjb.getUsers();
}
}
package com.jpa.model;
import java.io.Serializable;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* The persistent class for the usr01tbl database table.
*
*/
@Entity @XmlRootElement(name="User") @XmlType(propOrder= {"id","firstname","lastname"})
@Table(name="usr01tbl")
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="USR01TBL_ID_GENERATOR", sequenceName="USR01TBL_ID_SEQ")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="USR01TBL_ID_GENERATOR")
private Integer id;
@Column(name="firstname")
private String firstname;
@Column(name="lastname")
private String lastname;
public User() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
Next is to add your dynamic web project that includes SOAP web service to enterprise application project and deploy to Wildfly and check
Create Enterprise Application Project |
Select Runtime Environment |
Add Project to be deployed |
Finish |
address=http://localhost:8080/java-ee-02-jaxws/userCrudService
implementor=com.jaxws.webservice.UserCrudImp
serviceName={http://webservice.jaxws.com/}userCrudService
portName={http://webservice.jaxws.com/}userCrudPort
annotationWsdlLocation=null
wsdlLocationOverride=null
mtomEnabled=false
in your wildfly control portal you should see.implementor=com.jaxws.webservice.UserCrudImp
serviceName={http://webservice.jaxws.com/}userCrudService
portName={http://webservice.jaxws.com/}userCrudPort
annotationWsdlLocation=null
wsdlLocationOverride=null
mtomEnabled=false
Wildfly control Portal |
WSDL |
http://localhost:8080/java-ee-02-jaxws/userCrudService?wsdl
Test JAX-WS web service.
Eclipse is a excellent tool to test soap web service. I will use web service explorer to test web service.Open Web Service Explorer |
Open WSDL Page |
Input your WSDL |
Click Go |
Test getUsers |
Secure Web Service
In general cases, you don't just publish your web service API and just let any one to access it. You need to identify and give access to certain person to access it, this is concerned to security issue. In order to secure web service, you must apply SSL and HTTPS for encrypting the communication between server and client. And you must apply service authentication to verity access person. Service authentication could be done by application level or container level since you don't want to create every authentication verification for every web services you created.First you need to set up HTTPS for your Wildfly. You need to create key store. About how to create key store and set up HTTS you can refer here
$cd $JBOSS_HOME/standalone/configuration
$vi standalone.xml
and you just add as below$vi standalone.xml
<subsystem xmlns="urn:jboss:domain:webservices:2.0" statistics-enabled="true">
<modify-wsdl-address>true</modify-wsdl-address>
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<wsdl-secure-port>8443</wsdl-secure-port>
<wsdl-uri-scheme>https</wsdl-uri-scheme>
Now, restart your server and try to access your wsdl as below.<modify-wsdl-address>true</modify-wsdl-address>
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<wsdl-secure-port>8443</wsdl-secure-port>
<wsdl-uri-scheme>https</wsdl-uri-scheme>
<endpoint-config name="Standard-Endpoint-Config"/>
<endpoint-config name="Recording-Endpoint-Config">
<pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
<handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
</pre-handler-chain>
</endpoint-config>
<client-config name="Standard-Client-Config"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:weld:3.0"/>
https://localhost:8443/java-ee-01-jaxws/userCrudService?wsdl
and you can see your wsld as
Output WSDL's xml |
Create user and role
You can use add-user.sh to create user and role.
$cd $JBOSS_HOME/bin
$bash add-user.sh
What type of user do you wish to add?
a) Management User (mgmt-users.properties)
b) Application User (application-users.properties)
(a): b
Enter the details of the new user to add.
Using realm 'ApplicationRealm' as discovered from the existing property files.
Username : usr03
Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.
- The password should be different from the username
- The password should not be one of the following restricted values {root, admin, administrator}
- The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
Password :
Re-enter Password :
What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[ ]: webservice
About to add user 'usr03' for realm 'ApplicationRealm'
Is this correct yes/no? yes
Added user 'usr03' to file 'D:\Devs\wildfly-10.1.0.Final\standalone\configuration\application-users.properties'
Added user 'usr03' to file 'D:\Devs\wildfly-10.1.0.Final\domain\configuration\application-users.properties'
Added user 'usr03' with groups webservice to file 'D:\Devs\wildfly-10.1.0.Final\standalone\configuration\application-roles.properties'
Added user 'usr03' with groups webservice to file 'D:\Devs\wildfly-10.1.0.Final\domain\configuration\application-roles.properties'
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition <secret value="UWY0OGQ4dXYxMiFA" />
Press any key to continue . . .
create Group (webservice) |
create user (usr03) belong to webserivce group |
package com.web.service;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import com.jpa.model.User;
@RolesAllowed({"webservice"})
@WebService(
name="userCrud",
targetNamespace="https://wildfly.itstikk.pro"
)
@SOAPBinding(style=Style.RPC)
public interface UserCrud {
@WebMethod(action="save",operationName="saveUser")
@WebResult(name="saveResult")
public void save(@WebParam(name="userParam") User user);
@WebMethod(action="get",operationName="getUser")
@WebResult(name="user")
public List<User> getUsers();
}
Edit /WEB-INF/web.xml as below
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>java-ee-02-jaxws</display-name>
<security-constraint> <web-resource-collection>
<web-resource-name>webservice auth</web-resource-name>
<url-pattern>/*</url-pattern>
<!-- <http-method>POST</http-method> -->
</web-resource-collection>
<auth-constraint>
<role-name>webservice</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>ApplicationRealm</realm-name>
</login-config>
<security-role>
<role-name>webservice</role-name>
</security-role>
</web-app>
Then create jboss-web.xml and put as below.
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<context-root>java-ee-02-jaxws</context-root>
<security-domain>java:/jaas/other</security-domain>
</jboss-web>
Now your configuration file should be like below.<jboss-web>
<context-root>java-ee-02-jaxws</context-root>
<security-domain>java:/jaas/other</security-domain>
</jboss-web>
Configuration files |
authentication dialog |
WDSL output |
To test your webservice you can use SoapUI and use auth to create request.
Use SoapUI to test secure web service with authentication |
Reference
- MKyong JAX-WS web service tutorial
- Refer my source code here
- Use Soap UI to test SOAP web service
- Secure Web Service with Basic Authentication
- Set up Basic Authentication for Wildfly
No comments:
Post a Comment