6 Stimmen

Verwendung von Apache cxf mit spring mvc in einer einzigen Anwendung mit gemeinsamen Diensten

Ich arbeite derzeit ein Projekt, das auf Frühling MVC basiert, es ist nur ein Standardprojekt mit Frühling MVC-Vorlage. so habe ich web.xml und Servlet-context.xml.

Ich arbeite an der Hinzufügung von Apache cxf-Webdiensten in dieses Projekt und stoße auf einige Probleme bei der gemeinsamen Nutzung von Diensten mit bestehenden Spring MVC.

Mein anfänglicher Ansatz war der Versuch, Webdienste zum Laufen zu bringen, also sieht meine web.xml wie folgt aus:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets 
        and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml
        /WEB-INF/spring/jaxwsServlet/jaxwsServlet-context.xml
        </param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Process web service requests -->
    <servlet>
        <servlet-name>jaxws</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jaxws</servlet-name>
        <url-pattern>/industryAspectWS</url-pattern>
    </servlet-mapping>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

und meine jaxwsServlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:ws="http://jax-ws.dev.java.net/spring/core"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
       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
        classpath:spring-jax-ws-core.xsd
        http://jax-ws.dev.java.net/spring/servlet
        classpath:spring-jax-ws-servlet.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>   
    <wss:binding url="/industryAspectWS">
        <wss:service>
            <ws:service bean="#industryAspectWS"/>
        </wss:service>
    </wss:binding>

    <!-- Web service methods -->
    <bean id="industryAspectWS" class="com.example.ws.IndustryAspectWS"></bean>

    <context:component-scan base-package="com.example" />

    <beans:import resource="../HibernateTransaction.xml" />

    <beans:import resource="../JaxbMarshaller.xml" />

</beans>

Ich habe die kontext:komponenten-scan beans:import Abschnitte aus servlet-context.xml

Diese Konfiguration funktioniert gut, da ich in der Lage war, den Server hochzufahren, Webdienste aufzurufen und auch auf Servlet und JSP zuzugreifen. Da ich jedoch die Datei hibernateTransaction.xml in beiden Kontext-xml-Dateien zitiert habe, stelle ich fest, dass es zwei Sitzungsfabriken gibt.

Ich möchte alle Dienste (z. B. Hibernate) zwischen Apache cxf und Spring MVC-Controllern teilen, also habe ich versucht, Einstellungen in Root-context.xml zu setzen, es hat nicht funktioniert. Ich habe auch versucht, dies online zu suchen, habe aber keine vollständigen Beispiele für gemeinsam genutzte Dienste gefunden. Ist es möglich, dass wir eine Einstellung setzen können, um Dienste zwischen den beiden zu teilen?

\=================================================

Ich hatte einige Einstellungen ausprobiert, nachdem ich dies gepostet hatte, und dachte mir, wenn ich die Zeilen von

<context:component-scan base-package="com.example" />

et

<tx:annotation-driven transaction-manager="txManagerExample" />

Sowohl in der servlet-context.xml als auch in der jaxwsServlet-context.xml wird es funktionieren. Alle anderen Einstellungen können in der gemeinsamen Root-context.xml bleiben.

8voto

sourcedelica Punkte 23612

WSSpringServlet ist nicht CXF. Es ist Metro. Ich würde die Verwendung von CXF empfehlen. In diesem Fall haben Sie eine CXFServlet aber dann würden Sie CXF in Ihrem Haupt-Spring-Kontext einrichten (der, der von ContextLoaderListener .

Es würde folgendermaßen funktionieren: Ihr Hauptkontext würde alle gemeinsam genutzten Beans einschließlich CXF enthalten. Ihr Servlet-Kontext würde nur Ihre Controller enthalten. Da der Servlet-Kontext ein Kind des Hauptkontexts ist, hätten Ihre Controller auch Zugriff auf alles im Hauptkontext.

Siehe die Einbettung von CXF in eine Spring-Seite die CXF-Servlet-Transport-Seite und meine Antwort auf diese Frage über die gemeinsame Nutzung von Beans zwischen Servlet-Kontext und Hauptkontext.

0voto

MGorgon Punkte 2517

Dank an https://stackoverflow.com/a/30758664/2615824 :

Zwei Dispatcher (Spring MVC REST Controller und CXF JAX-WS) mit einem Spring Context, Java Config (kein xml-Zeug...) Beispiel:

WebApplicationInitializer:

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    rootContext.register(MyServiceConfig.class);
    servletContext.addListener(new ContextLoaderListener(rootContext));

    AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
    webContext.setParent(rootContext);

    ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("REST dispatcher", new DispatcherServlet(webContext));
    restDispatcher.setLoadOnStartup(1);
    restDispatcher.addMapping("/api/*");

    ServletRegistration.Dynamic cxfDispatcher = servletContext.addServlet("CXF dispatcher", CXFServlet.class);
    cxfDispatcher.setLoadOnStartup(1);
    cxfDispatcher.addMapping("/services/*");
}

Konfig:

@Configuration
@ComponentScan("my.root.package")
@ImportResource(value = {"classpath:META-INF/cxf/cxf.xml"})
@PropertySource("classpath:app-env.properties")
@PropertySource("classpath:app.properties")
@EnableWebMvc
public class MyServiceConfig {

    @Autowired
    private Bus cxfBus;

    @Autowired
    private CxfEndpointImpl cxfEndpoint;

    @Bean
    public Endpoint cxfService() {
        EndpointImpl endpoint = new EndpointImpl(cxfBus, cxfEndpoint);
        endpoint.setAddress("/CxfEndpointImpl");
        endpoint.setWsdlLocation("classpath:CxfService/CxfService-v1.0.wsdl");
        endpoint.publish();
        return endpoint;
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

Beispiel für einen CXF-Endpunkt (WSDL zuerst):

@Component
@WebService(
        endpointInterface = ".....v1_0.CxfServicePort",
        targetNamespace = "http://..../service/CxfService/v1_0",
        serviceName = "CxfService",
        portName = "CxfServicePort",
        wsdlLocation = "classpath:CxfService/CxfService-v1.0.wsdl")
@MTOM(enabled = true)
@SchemaValidation(type = SchemaValidationType.BOTH) 
@InInterceptors(classes = NoBinaryContentLoggingInInterceptor.class)
@OutInterceptors(classes = NoBinaryContentLoggingOutInterceptor.class)
@EndpointProperty(key = "ws-security.callback-handler", ref = "cxfEndpointSecurityHandler")
public class CxfEndpointImpl implements CxfServicePort {

    //...

}

Beispiel für einen REST-Controller:

@RestController
@RequestMapping(value = "/system", produces = MediaType.APPLICATION_JSON_VALUE)
public class RestController {

    //...
}

Adresse der CXF-Endpunktbereitstellung:

ip:port/tomcat-context/services/CxfEndpointImpl?wsdl

Spring REST Controller Einsatzadresse:

ip:port/tomcat-context/api/system

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X