Announcement Announcement Module
Collapse
No announcement yet.
How to save the XML Request Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to save the XML Request

    Hi everybody,

    I have a little problem: for the project I am working on, I need to save incoming requests but for what I understand the requests are unmarshalled as soon as they are intercepted by the MessageDispatcherServlet, I am not able to retrieve the XML message.

    I think I can solve this by using a filter but I think there's a better way to do, just can't get it...

    If anyone knows, it will be very helpful.

    Thanks

    (Sorry for my english)

  • #2
    I found a solution for my problem (not the best solution IMO but is efficient for what I had to do):

    In my Endpoint, I build the XML by marshaling my request object (which is exactly the opposite of what my JAXB2Marshaller do with incoming XML request...)

    Code:
    @Endpoint
    public class HolidayServiceEndpoint{
    
    @PayloadRoot(localPart = "holidayRequest", namespace = "http://localhost:8080/holidayService/")
        public HolidayResponse getHolidayResponse(HolidayRequest holidayRequest) {
         
    Jaxb2Marshaller marshaller = new JAXB2Marshaller();
    marshaller.setContextPath("com.myexample.holiday"); //package name
    StringResult toto = new StringResult();
    marshaller.marshal(holidayRequest, toto);
    System.out.println(toto);
    }
    I'm still open for various way to do that.

    Comment


    • #3
      PayloadLoggingInterceptor is there for that reason. If needed, create a special logger to do just that.

      Otherwise write your own interceptor, it is in the spirit of Spring's design to use interceptor over what you did to achieve that. The solution that worked for you can't be easily changed. Interceptors can be configured.

      I would definitely go for PayloadLoggingInterceptor. If that doesn't work for you, create your own and implement handleRequest to do your logging.

      Comment


      • #4
        Thank you, yes I finally understand how the PayloadLoggingInterceptor works, by declaring this bean in spring-ws-servlet.xml:

        Code:
        <bean id="Validating" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
        	<property name="interceptors">
        		<list>
        			<bean id="RequestLogger" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor">
        				<description>This interceptor logs the message payload.</description>
        				<property name="logRequest" value="true" />
        				<property name="logResponse" value="false" />
        			</bean>
        			<bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
        				<property name="schemas">
        					<list>
        						<value>/WEB-INF/services/ParamService.xsd</value>
        						<value>/WEB-INF/services/AdminService.xsd</value>
        						<value>/WEB-INF/services/Service.xsd</value>
        					</list>
        				</property>
        				<property name="validateRequest" value="true" />
        				<property name="validateResponse" value="true" />
        			</bean>
        			<bean id="ResponseLogger" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor">
        				<description>This interceptor logs the message payload.</description>
        				<property name="logRequest" value="false" />
        				<property name="logResponse" value="true" />
        			</bean>
        		</list>
        	</property>
        </bean>
        with an appropriate log4j.xml

        I hope this will be helpful for someone

        Comment


        • #5
          good, any special reason in creating separate request and response logger without setting LoggerName property?

          Also,
          <list><bean

          can't have id, no?

          Comment


          • #6
            Yes there is a reason, I forgot to speak about that:

            at first I just had this:

            Code:
            <bean id="Validating" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
            	<property name="interceptors">
            		<list>
            			<bean id="RequestLogger" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor">
            				<description>This interceptor logs the message payload.</description>
            				<property name="logRequest" value="true" />
            				<property name="logResponse" value="true" />
            			</bean>
            			<bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
            				<property name="schemas">
            					<list>
            						<value>/WEB-INF/services/ParamService.xsd</value>
            						<value>/WEB-INF/services/AdminService.xsd</value>
            						<value>/WEB-INF/services/Service.xsd</value>
            					</list>
            				</property>
            				<property name="validateRequest" value="true" />
            				<property name="validateResponse" value="true" />
            			</bean>			
            		</list>
            	</property>
            </bean>
            but it only logged the request, it seems that the order of interceptors matters, I don't know exactly how and why but I fixed the problem by logging request before validating and response after validating.

            I don't get:
            Also,
            <list><bean

            can't have id, no?
            Do you mean that <bean/> declared into a <list></list> can't have id?

            Comment


            • #7
              Instead of can't, i meant it shouldn't. The whole purpose of enclosing the bean def inside the property is so it doesn't get ref from outside. If needed to be ref from outside, it is better to have the bean extracted outside and use ref inside the list.

              Code:
              public class SimplePayloadLoggingInterceptor implements EndpointInterceptor {
                  private static final Log logger = LogFactory.getLog(SimplePayloadLoggingInterceptor.class);
              
                  public boolean handleFault(MessageContext messageCtx, Object endpoint) throws Exception {
                      if(logger.isDebugEnabled()) {
                          logger.debug("fault - ");
                          logMessageSource(getSource(messageCtx.getResponse()));
                      }
                      return true;
                  }
              
                  public boolean handleRequest(MessageContext messageCtx, Object endpoint) throws Exception {
                      if(logger.isDebugEnabled()) {
                          logger.debug("request - ");
                          logMessageSource(getSource(messageCtx.getResponse()));
                      }
                      return true;
                  }
              
                  public boolean handleResponse(MessageContext messageCtx, Object endpoint) throws Exception {
                      if(logger.isDebugEnabled()) {
                          logger.debug("response -");
                          logMessageSource(getSource(messageCtx.getRequest()));
                      }
                      return true;
                  }
              
                  private void logMessageSource(Source source) {
                      try {
                          Result result = new StringResult();
                          Transformer transform = TransformerFactory.newInstance().newTransformer();
                          transform.transform(source, result);
                          logger.debug(result.toString());
                      } catch (Exception e) {
                          logger.warn(e);
                      }
                  }
              
                  private Source getSource(WebServiceMessage message) {
                      return message.getPayloadSource();
                  }
              
              }
              I have a bean like this which I usually put at the top intereceptor, so nothing espaces it. It logs fault messages too. It is identical to PayloadLogging interceptor except that it logs fault too.

              Could the spring ws team parameterise the fault logging, so PayloadLoggingInterceptor could serve a wider purpose ie. log fault messages too.
              Last edited by portlet2; Aug 18th, 2009, 08:33 PM.

              Comment

              Working...
              X