简体   繁体   中英

Spring SOAP Endpoint - Cache JaxbContext

I wrote a simple SOAP endpoint essentially following the Spring tutorial found here: https://spring.io/guides/gs/producing-web-service/

Below is the class which is used to intercept the requests (assume repository object injected):

@Endpoint
public class SampleEndpoint {

  @PayloadRoot(namespace = NAMESPACE_URI, localPart = "SampleRequest")
  public
  @ResponsePayload
  JAXBElement<SampleResponseType> sampleQuery(
        @RequestPayload JAXBElement<SampleRequestType> request) {

    ObjectFactory factory = new ObjectFactory();
    SampleResponseType response = repository.query(request.getValue());
    JAXBElement<SampleResponseType> jaxbResponse = factory.createSampleResponse(response);
    return jaxbResponse;

  }

}

The service performs correctly. One issue I'm running into is performance, particularly with unmarshalling the response. On average it's taking seconds to unmarshall the object into an XML response. Is there a way to cache/inject the JaxbContext Spring is using for this process to improve on this time?

Here's the web service configuration file I'm using for this endpoint. I've tried alternating between Saaj and Axiom message factories but didn't see much performance change:

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

@Bean
public SaajSoapMessageFactory soap12MessageFactory() {
    SaajSoapMessageFactory factory = new SaajSoapMessageFactory();
    factory.setSoapVersion(SoapVersion.SOAP_12);
    return factory;
}

@Bean
public AxiomSoapMessageFactory axiomSoapMessageFactory() {
    AxiomSoapMessageFactory factory = new AxiomSoapMessageFactory();
    factory.setSoapVersion(SoapVersion.SOAP_12);
    factory.setPayloadCaching(false);
    return factory;
}

@Bean
public ServletRegistrationBean dispatcherServlet(
        ApplicationContext applicationContext) {
    MessageDispatcherServlet servlet = new MessageDispatcherServlet();
    servlet.setApplicationContext(applicationContext);
    servlet.setTransformWsdlLocations(true);
    servlet.setMessageFactoryBeanName("soap12MessageFactory");
    return new ServletRegistrationBean(servlet, "/ws/*");
}

@Bean(name = "wsdlname")
public DefaultWsdl11Definition xcpdDefaultXcpdWsdl11Definition(XsdSchema
     schema) {
    DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
    wsdl11Definition.setCreateSoap11Binding(false);
    wsdl11Definition.setCreateSoap12Binding(true);
    wsdl11Definition.setPortTypeName("xcpdPort");
    wsdl11Definition.setLocationUri("/ws");
    wsdl11Definition
            .setTargetNamespace("http://somenamespace.org/");
    wsdl11Definition.setSchema(schema);
    return wsdl11Definition;
}

@Bean
public XsdSchema schema() {
    return new SimpleXsdSchema(
            new ClassPathResource(
                    "schema.xsd"));
}
}

We obtained a solution to the issue two days ago. The first issue we saw was that the client version of the JVM was installed on the server. I installed the server build of the JVM and changed Tomcat to use that instance. The performance of some of the web services improved dramatically. Previously simple requests were taking three seconds, now they are taking 250 ms. However when testing the Spring service I wrote, I didn't see much of an improvement.

To resolve this last issue, I added the following to the Java options for Tomcat:

-Dcom.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=true

After restarting the Tomcat instance, the response times of the services are now under one second each. Previously requests were taking up to 30 seconds to complete. The server JRE we used is the following:

http://www.oracle.com/technetwork/java/javase/downloads/server-jre8-downloads-2133154.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM