My previous blog I explain some SOA concept. Now In this blog I am jumping to some practical and explaining how to setup some basic web services with Spring framework and how to implement some security with web Services. To run this example you need JDK 1.5+ and spring framework 3.0+I created some basic configuration. Here are list.
1. applicationContext-service.xml — It has some basic configuration of web service in spring
2. HelloWorldWS.java — This class is exposing webservice
3. HelloWorldServiceHandler.java — This class is monitoring incoming request and outgoing message. Here we implement WS-security.
4. HelloWorldManager.java — This class is interface for business implementation.
5. HelloWorldManagerImpl.java— This class has business implementation.Now lets start how I implemented this web service. here are codes.
1. applicationContext-service.xml—
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
- xmlns:ws="http://jax-ws.dev.java.net/spring/core"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://jax-ws.dev.java.net/spring/core
- http://jax-ws.dev.java.net/spring/core.xsd
- http://jax-ws.dev.java.net/spring/servlet
- http://jax-ws.dev.java.net/spring/servlet.xsd">
- <bean id="constantMap" />
- <ws:service id="SOAPservice" bean="#helloWorldWS">
- <ws:handlers>
- <ref bean="helloWorldHandler" />
- </ws:handlers>
- </ws:service>
- <wss:bindings id="jaxWs">
- <wss:bindings>
- <wss:binding url="/webservices/HelloWorldService">
- <wss:service>
- <ref bean="SOAPservice"/>
- </wss:service>
- </wss:binding>
- </wss:bindings>
- </wss:bindings>
- <bean id="helloWorldHandler">
- <property name="constantMap" ref="constantMap" />
- </bean>
- <!-- Injecting DAO Object -->
- <bean id="helloWorldManager">
- <property name="target">
- <bean>
- <property name="userDAO"><ref bean="userDAO"/></property>
- </bean>
- </property>
- </bean>
- <bean id="helloWorldWS">
- <property name="helloWorldManager"><ref bean="helloWorldManager"/></property>
- </bean>
- </beans>
2. HelloWorldWS.java
- package com.vanrish.service;
- import javax.annotation.Resource;
- import javax.jws.WebMethod;
- import javax.jws.WebParam;
- import javax.jws.WebResult;
- import javax.jws.WebService;
- import javax.jws.soap.SOAPBinding;
- import javax.xml.ws.WebServiceContext;
- import com.vanrish.service.HelloWorldManager;
- import com.vanrish.xml.schema.PeopleInfoRequest;
- import com.vanrish.xml.schema.PeopleInfoResponse;
- @WebService (targetNamespace="http://www.vanrish.com/helloWorldService",serviceName = "HelloWorldService")
- @SOAPBinding(style=SOAPBinding.Style.DOCUMENT, use=SOAPBinding.Use.LITERAL, parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
- public class HelloWorldWS {
- private HelloWorldManager helloWorldManager;
- @Resource
- WebServiceContext context;
- @WebMethod(exclude=true)
- public void setHelloWorldManager(HelloWorldManager helloWorldManager) {
- this.helloWorldManager = helloWorldManager;
- }
- @WebMethod(operationName = "getPeopleInfo")
- @WebResult(name = "PeopleInfo", partName = "PeopleInfo")
- public PeopleInfoResponse getPeopleInfo(@WebParam(name = "PeopleInfoRequest", partName = "PeopleInfoRequest",targetNamespace="http://www.vanrish.com/helloWorldService") PeopleInfoRequest peopleInfoRequest) throws Exception {
- return helloWorldManager.getPeopleInfo(peopleInfoRequest);
- }
- }
3. HelloWorldServiceHandler.java
- package com.vanrish.service.handler;
- import java.io.ByteArrayOutputStream;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Set;
- import javax.xml.namespace.QName;
- import javax.xml.soap.SOAPElement;
- import javax.xml.soap.SOAPEnvelope;
- import javax.xml.soap.SOAPHeader;
- import javax.xml.soap.SOAPMessage;
- import javax.xml.soap.SOAPPart;
- import javax.xml.ws.handler.MessageContext;
- import javax.xml.ws.handler.soap.SOAPHandler;
- import javax.xml.ws.handler.soap.SOAPMessageContext;
- import javax.xml.soap.Name;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- public class HelloWorldServiceHandler implements SOAPHandler {
- private static final Log log = LogFactory.getLog(HelloWorldServiceHandler.class);
- /** The Constant USERNAME_TOKEN_STRING. */
- private static final String USERNAME_TOKEN_STRING = "UsernameToken";
- /** The Constant USERNAME_STRING. */
- private static final String USERNAME_STRING = "Username";
- /** The Constant PASSWORD_STRING. */
- private static final String PASSWORD_STRING = "Password";
- private Map constantMap;
- public Set getHeaders() {
- return null;
- }
- public void close(MessageContext context) {
- }
- public boolean handleFault(SOAPMessageContext context) {
- logToSystemOut(context);
- return true;
- }
- public boolean handleMessage(SOAPMessageContext context) {
- Boolean outboundProperty = (Boolean) context
- .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
- boolean isSoapRequestHandle = false;
- if (outboundProperty.booleanValue()) {
- isSoapRequestHandle = true;
- /* ************************************************************************
- * If you are manupulating outgoing header then you need to add this code
- *
- **************************************************************************
- * try { SOAPMessage message = context.getMessage();
- *
- * SOAPPart sp = message.getSOAPPart();
- *
- * SOAPEnvelope envelope = sp.getEnvelope();
- *
- * SOAPHeader header = envelope.addHeader();
- *
- * SOAPElement security = header.addChildElement("Security", "wsse",
- * "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
- * );
- *
- * SOAPElement usernameToken =
- * security.addChildElement("UsernameToken", "wsse");
- * usernameToken.addAttribute(new QName("xmlns:wsu"),
- * "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
- * );
- *
- * SOAPElement username = usernameToken.addChildElement("Username",
- * "wsse"); username.addTextNode("TestUser");
- *
- * SOAPElement password = usernameToken.addChildElement("Password",
- * "wsse"); password.setAttribute("Type",
- * "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
- * ); password.addTextNode("TestPassword");
- *
- * //Print out the outbound SOAP message to System.out
- * message.writeTo(System.out); System.out.println("");
- *
- *
- *
- * }catch (Exception e) { e.printStackTrace();
- *
- * }
- */
- } else {
- try {
- SOAPMessage message = context.getMessage();
- SOAPPart sp = message.getSOAPPart();
- SOAPEnvelope envelope = sp.getEnvelope();
- SOAPHeader sh = envelope.getHeader();
- isSoapRequestHandle = processSOAPHeader(sh);
- message.writeTo(System.out);
-
- if (!isSoapRequestHandle) {
- SOAPElement errorMessage = sh.addChildElement(
- "errorMessage", "error",
- "http://vanrish.com/helloService/error");
- SOAPElement error = errorMessage.addChildElement("error");
- error.addTextNode("Authentication Failed !!!");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- logToSystemOut(context);
- return isSoapRequestHandle;
- }
- private void logToSystemOut(SOAPMessageContext smc) {
- Boolean outboundProperty = (Boolean) smc
- .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
- if (outboundProperty.booleanValue()) {
- log.debug("\nOutgoing message:");
- } else {
- log.debug("\nIncoming message:");
- }
- SOAPMessage message = smc.getMessage();
- try {
- log.debug(handleRequestAndResponse(message));
- } catch (Exception e) {
- System.out.println("Exception in handler: " + e);
- }
- }
- private String handleRequestAndResponse(SOAPMessage msg) {
- ByteArrayOutputStream obj = new ByteArrayOutputStream();
- try {
- msg.writeTo(obj);
- return obj.toString();
- } catch (Exception ex) {
- obj = null;
- ex.printStackTrace();
- }
- return "";
- }
- private boolean processSOAPHeader(SOAPHeader sh) {
- boolean authenticated = false;
- // look for authentication header element inside the HEADER block
- Iterator childElems = sh.getChildElements();
- SOAPElement child = extractUserNameInfo(childElems);
- if (child != null) {
- // call method to perform authentication
- authenticated = authenticateRequest(child);
- }
- return authenticated;
- }
- private SOAPElement extractUserNameInfo(Iterator childElems) {
- SOAPElement child = null;
- Name sName;
- // iterate through child elements
- while (childElems.hasNext()) {
- Object elem = childElems.next();
- if (elem instanceof SOAPElement) {
- // Get child element and its name
- child = (SOAPElement) elem;
- sName = child.getElementName();
- // Check whether there is a UserNameToken element
- if (!USERNAME_TOKEN_STRING.equalsIgnoreCase(sName
- .getLocalName())) {
- if (child.getChildElements().hasNext()) { // TODO check
- logic
- return extractUserNameInfo(child.getChildElements());
- }
- }
- }
- }
- return child;
- }
- private boolean authenticateRequest(SOAPElement element) {
- boolean authenticated = false;
- // variable for user name and password
- String userName = null;
- String password = null;
- Name sName;
- // get an iterator on child elements of SOAP element
- Iterator childElems = element.getChildElements();
- SOAPElement child;
- // loop through child elements
- while (childElems.hasNext()) {
- // get next child element
- Object elem = childElems.next();
- if (elem instanceof SOAPElement) {
- child = (SOAPElement) elem;
- // get the name of SOAP element
- sName = child.getElementName();
- // get the value of username element
- if (USERNAME_STRING.equalsIgnoreCase(sName.getLocalName())) {
- userName = child.getValue();
- } else if (PASSWORD_STRING.equalsIgnoreCase(sName
- .getLocalName())) {
- // get the value of password element
- password = child.getValue();
- }
- if (userName != null && password != null) {
-
- authenticated = getUserAuth(userName, password);
- break;
- }
- }
- }
- if (userName == null || password == null) {
- log.warn("Username or password is empty. userName : [" + userName
- + "], password : [" + password + "]");
- }
- return authenticated;
- }
- public Map getConstantMap() {
- return constantMap;
- }
- public void setConstantMap(Map constantMap) {
- this.constantMap = constantMap;
- }
- private boolean getUserAuth(String username, String password) {
- //Constant Map populated with database information
- String dbUserId = (String) constantMap.get("useIdFormDatabase");
- String dbPassword = (String) constantMap
- .get("passwordFormDatabase");
- if (dbUserId.equalsIgnoreCase(username) && dbPassword.equals(password)) {
- return true;
- }
- return false;
- }
- }
4. HelloWorldManager.java —
- package com.vanrish.service;
- import com.vanrish.xml.schema.PeopleInfoRequest;
- import com.vanrish.xml.schema.PeopleInfoResponse;
- public interface HelloWorldManager {
- public PeopleInfoResponse getPeopleInfo(PeopleInfoRequest peopleInfoRequest) throws Exception;
- }
5. HelloWorldManagerImpl.java —
- package com.vanrish.service.impl;
- import java.math.BigDecimal;
- import java.math.BigInteger;
- import java.util.ArrayList;
- import java.util.Calendar;
- import java.util.Date;
- import java.util.GregorianCalendar;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import javax.xml.datatype.DatatypeConfigurationException;
- import javax.xml.datatype.DatatypeConstants;
- import javax.xml.datatype.DatatypeFactory;
- import javax.xml.datatype.XMLGregorianCalendar;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
- import com.vanrish.dao.UserDAO;
- import com.vanrish.model.PeopleVO;
- import com.vanrish.service.HelloWorldManager;
- import com.vanrish.xml.schema.ObjectFactory;
- import com.vanrish.xml.schema.Person;
- import com.vanrish.xml.schema.PeopleInfoRequest;
- import com.vanrish.xml.schema.PeopleInfoResponse;
- public class HelloWorldManagerImpl implements HelloWorldManager {
- private UserDAO userDAO;
- public PeopleInfoResponse getPeopleInfo(PeopleInfoRequest peopleInfoRequest) throws Exception {
- ObjectFactory factory = new ObjectFactory();
- PeopleInfoResponse peopleInfoResponse = factory.createPeopleInfoResponse();
- PeopleVO peopleVO = new PeopleVO();
- peopleVO.setPeopleId(peopleInfoRequest.getPeopleId());
- peopleVO = userDAO.getPeopleInfo(peopleVO);
- Person person = factory.createPerson();
- person.setFirstName(peopleVO.getFirstName());
- person.setLastName(peopleVO.getLastName());
- person.setType(peopleVO.getPeopleType());
- person.setCreateDate(getXmlDate(peopleVO.getCreateDate()));
- peopleInfoResponse.setPerson(person);
- peopleInfoResponse.setMessage(SUCCESS_MESSAGE);
- peopleInfoResponse.setSuccess(true);
- return peopleInfoResponse;
- }
- private XMLGregorianCalendar getXmlDate(Date date) {
- try {
- GregorianCalendar cal = new GregorianCalendar();
- cal.setTime(date);
- XMLGregorianCalendar gc = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
- gc.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
- gc.setTime(DatatypeConstants.FIELD_UNDEFINED,
- DatatypeConstants.FIELD_UNDEFINED,
- DatatypeConstants.FIELD_UNDEFINED);
- return gc;
- } catch (DatatypeConfigurationException e) {
- log.warn("Cannot format expxiration date: " + date);
- return null;
- }catch(Exception ex){
- log.warn("Cannot format expxiration date: " + ex);
- return null;
- }
- }
- public void setUserDAO(UserDAO userDAO) {
- this.userDAO = userDAO;
- }
- }
Rajnish Kumar is CTO of Vanrish Technology with Over 25 years experience in different industries and technology. He is very passionate about innovation and latest technology like APIs, IOT (Internet Of Things), Artificial Intelligence (AI) ecosystem and Cybersecurity. He present his idea in different platforms and help customer to their digital transformation journey.