Results 1 to 3 of 3

Thread: Configuring JiBXMarshaller with GenericMarshallingMethodEndpointAdapter

Hybrid View

  1. #1
    Join Date
    Jun 2008
    Posts
    11

    Default Configuring JiBXMarshaller with GenericMarshallingMethodEndpointAdapter

    Hello,
    I am developing a prototype to show how JIBXMarshaller can be used with Spring-WS. I modified the STS Spring-ws tutorial to provide 2 methods on the endpoint using the @PayloadRoot annotation as follows.

    @PayloadRoot(localPart = "HolidayRequest", namespace = "http://mycompany.com/hr/schemas")
    public void bookHoliday(HolidayRequest holidayRequest) throws Exception {

    Date startDate = holidayRequest.getHoliday().getStartDate();
    Date endDate = holidayRequest.getHoliday().getEndDate();
    String empName = holidayRequest.getEmployee().getFirstName() + " " + holidayRequest.getEmployee().getLastName();
    humanResourceService.bookHoliday(startDate, endDate, empName);
    }

    @PayloadRoot(localPart = "Employee", namespace = "http://mycompany.com/hr/schemas")
    public Holiday getHoliday(Employee employee) throws Exception {
    return humanResourceService.getHoliday(employee.getFirstN ame() + " " + employee.getLastName());
    }


    My spring configuration file looks like this.

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oxm="http://www.springframework.org/schema/oxm"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-2.0.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd">


    <bean id="holidayEndpoint" class="com.mycompany.hr.ws.HolidayAnnotationEndpoi nt">
    <constructor-arg ref="hrService"/>
    </bean>

    <bean id="hrService" class="com.mycompany.hr.service.StubHumanResourceS ervice"/>

    <bean class="org.springframework.ws.server.endpoint.mapp ing.PayloadRootAnnotationMethodEndpointMapping">
    <property name="interceptors">
    <bean class="org.springframework.ws.server.endpoint.inte rceptor.PayloadLoggingInterceptor"/>
    </property>
    </bean>

    <bean id="holidayRequestMAdapter" class="org.springframework.ws.server.endpoint.adap ter.GenericMarshallingMethodEndpointAdapter">
    <constructor-arg ref="holidayRequestM"/>
    </bean>

    <bean id="holidayMAdapter" class="org.springframework.ws.server.endpoint.adap ter.GenericMarshallingMethodEndpointAdapter">
    <constructor-arg ref="holidayM"/>
    </bean>
    <bean id="employeeMAdapter" class="org.springframework.ws.server.endpoint.adap ter.GenericMarshallingMethodEndpointAdapter">
    <constructor-arg ref="employeeM"/>
    </bean>

    <oxm:jibx-marshaller id="holidayRequestM" target-class="com.mycompany.hr.model.HolidayRequest"/>
    <oxm:jibx-marshaller id="holidayM" target-class="com.mycompany.hr.model.Holiday"/>
    <oxm:jibx-marshaller id="employeeM" target-class="com.mycompany.hr.model.Employee"/>


    <bean id="holiday" class="org.springframework.ws.wsdl.wsdl11.DynamicW sdl11Definition">
    <property name="builder">
    <bean class="org.springframework.ws.wsdl.wsdl11.builder. XsdBasedSoap11Wsdl4jDefinitionBuilder">
    <property name="schema" value="/WEB-INF/hr.xsd"/>
    <property name="portTypeName" value="HumanResource"/>
    <property name="locationUri" value="http://localhost:8082/ws-tutorial/services"/>
    <property name="targetNamespace" value="http://mycompany.com/hr/definitions"/>
    </bean>
    </property>
    </bean>

    </beans>


    Although I am able to successfully call the method bookHoliday() where the HolidayRequest rootElement gets uinmarshalled to the HolidayRequest object, I get the following error while trying to call getHoliday() method. I do not know why even though I have provided the end point adapter for the objects being received and returned by this method as you can see above.
    *****************
    Stack Trace Begin
    ***************
    2009-06-25 15:40:27,795 DEBUG [org.springframework.ws.soap.server.SoapMessageDisp atcher] - Testing endpoint adapter [org.springframework.ws.server.endpoint.adapter.Gen ericMarshallingMethodEndpointAdapter@33c658]
    2009-06-25 15:40:27,857 DEBUG [org.springframework.ws.server.endpoint.adapter.Gen ericMarshallingMethodEndpointAdapter] - Unmarshalled payload request to [com.mycompany.hr.model.HolidayRequest@1f10a67]
    2009-06-25 15:40:27,857 INFO [com.mycompany.hr.service.StubHumanResourceService] - Booking holiday for [Sun Dec 16 16:00:00 PST 2001-Wed Jul 16 17:00:00 PDT 2003] for [Rajesh Nerurkar]
    2009-06-25 15:40:27,857 DEBUG [org.springframework.ws.server.MessageTracing.sent] - MessageDispatcher with name 'spring-ws' sends no response for request [SaajSoapMessage {http://mycompany.com/hr/schemas}HolidayRequest]
    2009-06-25 15:40:27,857 DEBUG [org.springframework.ws.transport.http.MessageDispa tcherServlet] - Successfully completed request
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.transport.http.WebServiceMe ssageReceiverHandlerAdapter] - Accepting incoming [org.springframework.ws.transport.http.HttpServletC onnection@1cee792] to [http://localhost:8082/ws-tutorial/services]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.server.MessageTracing.recei ved] - Received request [SaajSoapMessage {http://mycompany.com/hr/schemas}Employee]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.server.endpoint.mapping.Pay loadRootAnnotationMethodEndpointMapping] - Looking up endpoint for [{http://mycompany.com/hr/schemas}Employee]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.soap.server.SoapMessageDisp atcher] - Endpoint mapping [org.springframework.ws.server.endpoint.mapping.Pay loadRootAnnotationMethodEndpointMapping@16b9e62] maps request to endpoint [public com.mycompany.hr.model.Holiday com.mycompany.hr.ws.HolidayAnnotationEndpoint.getH oliday(com.mycompany.hr.model.Employee) throws java.lang.Exception]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.server.endpoint.interceptor .PayloadLoggingInterceptor] - Request: <hr:Employee xmlns:hr="http://mycompany.com/hr/schemas"><hr:Number>1</hr:Number><hr:FirstName>Rajesh</hr:FirstName><hr:LastName>Nerurkar</hr:LastName></hr:Employee>
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.soap.server.SoapMessageDisp atcher] - Testing endpoint adapter [org.springframework.ws.server.endpoint.adapter.Gen ericMarshallingMethodEndpointAdapter@33c658]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.soap.server.SoapMessageDisp atcher] - Testing endpoint adapter [org.springframework.ws.server.endpoint.adapter.Gen ericMarshallingMethodEndpointAdapter@1f2af1c]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.soap.server.SoapMessageDisp atcher] - Testing endpoint adapter [org.springframework.ws.server.endpoint.adapter.Gen ericMarshallingMethodEndpointAdapter@1c6866d]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.soap.server.SoapMessageDisp atcher] - Endpoint invocation resulted in exception - responding with Fault
    java.lang.IllegalStateException: No adapter for endpoint [public com.mycompany.hr.model.Holiday com.mycompany.hr.ws.HolidayAnnotationEndpoint.getH oliday(com.mycompany.hr.model.Employee) throws java.lang.Exception]: Does your endpoint implement a supported interface like MessageHandler or PayloadEndpoint? at org.springframework.ws.server.MessageDispatcher.ge tEndpointAdapter(MessageDispatcher.java:279)
    at org.springframework.ws.server.MessageDispatcher.di spatch(MessageDispatcher.java:220)
    at org.springframework.ws.server.MessageDispatcher.re ceive(MessageDispatcher.java:168)
    at org.springframework.ws.transport.support.WebServic eMessageReceiverObjectSupport.handleConnection(Web ServiceMessageReceiverObjectSupport.java:88)
    at org.springframework.ws.transport.http.WebServiceMe ssageReceiverHandlerAdapter.handle(WebServiceMessa geReceiverHandlerAdapter.java:57)
    at org.springframework.ws.transport.http.MessageDispa tcherServlet.doService(MessageDispatcherServlet.ja va:230)
    at org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:476)
    at org.springframework.web.servlet.FrameworkServlet.d oPost(FrameworkServlet.java:441)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:710)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:803)
    at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.servic e(CoyoteAdapter.java:263)
    at org.apache.coyote.http11.Http11Processor.process(H ttp11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11Conn ectionHandler.process(Http11Protocol.java:584)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run( JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:595)
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.server.MessageTracing.sent] - Sent response [SaajSoapMessage {http://schemas.xmlsoap.org/soap/envelope/}Fault] for request [SaajSoapMessage {http://mycompany.com/hr/schemas}Employee]
    2009-06-25 15:40:27,873 DEBUG [org.springframework.ws.transport.http.MessageDispa tcherServlet] - Successfully completed request

    **************
    Stack Trace End
    *************
    Any help on this will be really appreciated!!
    Last edited by rnerurkar; Jun 25th, 2009 at 06:40 PM. Reason: Incomplete first time

  2. #2
    Join Date
    Sep 2007
    Posts
    5

    Default

    Have you set the namespace of the mappings?
    something like:
    <namespace uri="http://mycompany.com/hr/schemas" default="elements" prefix="tns" />

    There is another thing that is causing me a problem and it's too many GenericMarshallingMethodEndpointAdapter. I don't know why but it always get the first one. In you case would be holidayRequestMAdapter.

    I hope this helps you.

    Regards,

    torimpo

  3. #3
    Join Date
    Sep 2007
    Posts
    5

    Default

    to solve the problem of many marshallings I created a class called PayloadRootAnnotationMethodEndPointAdapter

    It's related to the PayloadRootAnnotationMethodEndpointMapping.

    Based on the localPart is the marshaller that uses.

    Here is the class.

    Code:
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.Iterator;
    
    import javax.xml.namespace.QName;
    import javax.xml.transform.TransformerFactory;
    
    import org.springframework.oxm.GenericUnmarshaller;
    import org.springframework.oxm.Marshaller;
    import org.springframework.oxm.Unmarshaller;
    import org.springframework.ws.WebServiceMessage;
    import org.springframework.ws.context.MessageContext;
    import org.springframework.ws.server.endpoint.MethodEndpoint;
    import org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter;
    import org.springframework.ws.server.endpoint.support.PayloadRootUtils;
    import org.springframework.ws.support.MarshallingUtils;
    
    public class PayloadRootAnnotationMethodEndPointAdapter extends
    		AbstractMethodEndpointAdapter {
    
    	private HashMap<String, Marshaller> marshallers;
    	private HashMap<String, Unmarshaller> unmarshallers;
    	private static TransformerFactory transformerFactory;
    
    	static {
    		transformerFactory = TransformerFactory.newInstance();
    	}
    
    	public PayloadRootAnnotationMethodEndPointAdapter(
    			HashMap<String, Marshaller> marshallers) {
    
    		this.marshallers = marshallers;
    		this.unmarshallers = new HashMap<String, Unmarshaller>();
    		for (String key : marshallers.keySet()) {
    			unmarshallers.put(key, (Unmarshaller) marshallers.get(key));
    		}
    	}
    
    	public PayloadRootAnnotationMethodEndPointAdapter(
    			HashMap<String, Marshaller> marshallers,
    			HashMap<String, Unmarshaller> unmarshallers) {
    		this.marshallers = marshallers;
    		this.unmarshallers = unmarshallers;
    	}
    
    	private Object unmarshalRequest(WebServiceMessage request)
    			throws IOException, Exception {
    
    		Object requestObject = MarshallingUtils.unmarshal(
    				getUnmarshaller(getLocalPart(request)), request);
    
    		if (logger.isDebugEnabled()) {
    			logger.debug("Unmarshalled payload request to [" + requestObject
    					+ "]");
    		}
    
    		return requestObject;
    	}
    
    	protected void invokeInternal(MessageContext messageContext, MethodEndpoint methodEndpoint) throws Exception {
    		WebServiceMessage request = messageContext.getRequest();
    		Object requestObject = unmarshalRequest(request);
    		Object responseObject = methodEndpoint.invoke(new Object[] { requestObject });
    		if (responseObject != null) {
    			WebServiceMessage response = messageContext.getResponse();
    			marshalResponse(responseObject, response, getLocalPart(request));
    		}
    	}
    
    	private void marshalResponse(Object responseObject, WebServiceMessage response, String localPart) throws IOException, Exception {
    		if (logger.isDebugEnabled()) {
    			logger.debug("Marshalling [" + responseObject + "] to response payload");
    		}
    		MarshallingUtils.marshal(getMarshaller(localPart), responseObject, response);
    	}
    
    	/**
    	 * @param methodEndpoint
    	 * @return
    	 * @see org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter#supportsInternal(org.springframework.ws.server.endpoint.MethodEndpoint)
    	 */
    	@Override
    	protected boolean supportsInternal(MethodEndpoint methodEndpoint) {
    		Method method = methodEndpoint.getMethod();
    		return supportsReturnType(method) && supportsParameters(method);
    	}
    
    	private boolean supportsReturnType(Method method) {
    		boolean support = false;
    		if (Void.TYPE.equals(method.getReturnType())) {
    			return true;
    		} else {
    			Iterator<Marshaller> it = marshallers.values().iterator();
    			while (it.hasNext() && support == false) {
    				Marshaller marshaller = it.next();
    				if (marshaller instanceof GenericUnmarshaller) {
    					GenericUnmarshaller genericUnmarshaller = (GenericUnmarshaller) marshaller;
    					support = genericUnmarshaller.supports(method.getGenericParameterTypes()[0]);
    				} else {
    					support = marshaller.supports(method.getParameterTypes()[0]);
    				}
    			}
    		}
    		return support;
    	}
    
    	private boolean supportsParameters(Method method) {
    		boolean support = false;
    		if (method.getParameterTypes().length >= 1) {
    			Iterator<Unmarshaller> it = unmarshallers.values().iterator();
    			while (it.hasNext() && support == false) {
    				Unmarshaller unmarshaller = it.next();
    				if (unmarshaller instanceof GenericUnmarshaller) {
    					GenericUnmarshaller genericUnmarshaller = (GenericUnmarshaller) unmarshaller;
    					support = genericUnmarshaller.supports(method.getGenericParameterTypes()[0]);
    				} else {
    					support = unmarshaller.supports(method.getParameterTypes()[0]);
    				}
    			}
    		}
    		return support;
    	}
    
    	private Unmarshaller getUnmarshaller(String key) throws Exception {
    			return unmarshallers.get(key);
    	}
    
    	private Marshaller getMarshaller(String key) throws Exception {
    			return marshallers.get(key);
    	}
    	
    	private String getLocalPart(WebServiceMessage message) throws Exception{
    		QName qname = PayloadRootUtils.getPayloadRootQName(message.getPayloadSource(), transformerFactory);
    		return qname.getLocalPart();
    	}
    }
    Is there another option?

    Thanks in advance,

    torimpo
    Last edited by torimpo; Jul 5th, 2009 at 12:42 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •