JAXとspringのシームレスな統合(一)
25988 ワード
JAX-WSとspringの統合にはいくつかの方法があります.
1つ目:
jaxws-rtによりwebserviceの起動を実現します.
OK:プロファイルsun-jaxwsを追加作成する必要があります.xmlでspringのオートインジェクション機能が使えず、BeanFactoryからbeanを取得するしか受信できません!
に頼る
Webで必要です.xmlでサーブレットを構成する
プロファイルを追加する必要があります:sun-jaxws.xml
2つ目(推奨):
springが提供するjarパッケージによるJAX-WSとのシームレスな統合
利点:webserviceオブジェクトはspringによって管理され、springは注入を完了することができます!
1、依存パッケージ(デフォルト依存spring 2.0を除外する必要があります.そうしないと、プロジェクトで使用されているspring 3.0と競合します)
pom.xml
2、WSSpringServiceの構成
3、jaxwsとspringの統合を別のプロファイルに配置する.xml
ネーミングスペースを導入し、eclipseにschemaファイルを導入します(XML Catalog:Add...)
(xsdファイルは、Maven Dependenciesのjaxws-spring-1.8.jarから入手可能)
xmlns:wsとxmlns:wssは新しく追加されたネーミングスペースです
4、web.xmlにインフラストラクチャを追加
5、webservice実装クラスで注釈を用いて注入を完了する
jettyサーバを起動し、次のアドレスにアクセスします.
http://localhost:8080/student-web/jaxws-spring?wsdl
完了!
クライアントの作成
クライアントとサービス側は異なる2つのアプリケーションであるため、本例ではサービス側はTomcatをコンテナとして、クライアントはjettyをコンテナとして使用する
1、サービス側のプラグインを修正し、tomcatを使用する
2、クライアントの作成開始
基本手順:
jaxws-maven-pluginを使用してwsdlをローカルjavaファイルに変換
springMVCによるプレゼンテーションレイヤの機能
Jaxws-springを使用してJAX-WSとspringを統合し、主にクライアントにendpointサービスオブジェクトを注入します.
maven-jetty-pluginプラグインを使用してjettyをクライアントのサーバとして使用
pom.xml
web.xml
srpingMVC-servlet.xml
applicationContext.xml
Controller
その間に2つの異常に遭遇して、とても苦労してやっと解決しました!
異常1
解決策:
jaxws-rtに依存することを増やして、この問題は解決しました!
異常二
解決策:
衝突を排除し、依存パケットはコンテナ内のjarパケットと衝突し、jaxws-rtとjaxws-springの依存からactivation 1を排除する.1.jar
1つ目:
jaxws-rtによりwebserviceの起動を実現します.
OK:プロファイルsun-jaxwsを追加作成する必要があります.xmlでspringのオートインジェクション機能が使えず、BeanFactoryからbeanを取得するしか受信できません!
に頼る
<!-- servlet jax -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
</dependency>
Webで必要です.xmlでサーブレットを構成する
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>StudentWsService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentWsService</servlet-name>
<url-pattern>/ws</url-pattern>
</servlet-mapping>
プロファイルを追加する必要があります:sun-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<!-- name implementation url-pattern -->
<endpoint name="StudentWsService"
implementation="com.hqh.student.ws.StudentWSServiceImpl"
url-pattern="/ws"/>
</endpoints>
2つ目(推奨):
springが提供するjarパッケージによるJAX-WSとのシームレスな統合
利点:webserviceオブジェクトはspringによって管理され、springは注入を完了することができます!
1、依存パッケージ(デフォルト依存spring 2.0を除外する必要があります.そうしないと、プロジェクトで使用されているspring 3.0と競合します)
pom.xml
<!-- spring servlet jax -->
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<!-- spring2.0 -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
2、WSSpringServiceの構成
<!-- spring jax -->
<servlet>
<servlet-name>StudentWsService-WSSpringServlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentWsService-WSSpringServlet</servlet-name>
<url-pattern>/jaxws-spring</url-pattern>
</servlet-mapping>
3、jaxwsとspringの統合を別のプロファイルに配置する.xml
ネーミングスペースを導入し、eclipseにschemaファイルを導入します(XML Catalog:Add...)
(xsdファイルは、Maven Dependenciesのjaxws-spring-1.8.jarから入手可能)
xmlns:wsとxmlns:wssは新しく追加されたネーミングスペースです
<?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:context="http://www.springframework.org/schema/context"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-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">
<context:annotation-config/>
<context:component-scan base-package="com.hqh.student"/>
<!-- url must same with the url pattern of StudentWsService-WSSpringServlet in web.xml -->
<wss:binding url="/jaxws-spring">
<wss:service>
<!-- bean "#",studentWsService bean -->
<ws:service bean="#studentWsService">
<ws:metadata>
<value>/WEB-INF/wsdl/student.xsd</value>
</ws:metadata>
</ws:service>
</wss:service>
</wss:binding>
<!-- ( :jaxws spring , , !) -->
<!-- Web service methods
<bean id="studentWsService" class="com.hqh.student.ws.StudentWSServiceImpl">
<property name="studentService" ref="StudentService"></property>
</bean>
<bean id="StudentService" class="com.hqh.student.service.StudentServiceImpl"/>
-->
</beans>
4、web.xmlにインフラストラクチャを追加
<!-- spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml,classpath:applicationContext-jaxws.xml</param-value>
</context-param>
5、webservice実装クラスで注釈を用いて注入を完了する
package com.hqh.student.ws;
import java.util.List;
import javax.annotation.Resource;
import javax.jws.WebService;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.util.WebUtils;
import com.hqh.student.context.BeanFactoryUtil;
import com.hqh.student.context.WebUtil;
import com.hqh.student.model.Reward;
import com.hqh.student.model.Student;
import com.hqh.student.service.StudentService;
@WebService(endpointInterface="com.hqh.student.ws.IStudentWSService",
serviceName="StudentWSService",
portName="studentServicePort",
targetNamespace="http://ws.student.hqh.com",
wsdlLocation="/WEB-INF/wsdl/student.wsdl")
// spring ,studentWsService bean name
@Component("studentWsService")
public class StudentWSServiceImpl implements IStudentWSService{
// private static final BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
// public StudentWSServiceImpl() {
// if(studentService==null) {
// studentService = factory.getBean(StudentService.class);
// }
// }
//
@Resource
private StudentService studentService;
@Override
public Student getStudent(String number) {
// studentService = (StudentService) WebUtil.getBean(StudentService.class);
// studentService = (StudentService) BeanFactoryUtil.getBean(StudentService.class);
return studentService.getStudent(number);
}
@Override
public List<Student> list() {
// studentService = (StudentService) WebUtil.getBean(StudentService.class);
// studentService = (StudentService) BeanFactoryUtil.getBean(StudentService.class);
return studentService.list();
}
@Override
public List<Reward> listReward(String number, String year) {
// studentService = (StudentService) WebUtil.getBean(StudentService.class);
// studentService = (StudentService) BeanFactoryUtil.getBean(StudentService.class);
return studentService.listReward(number, year);
}
}
jettyサーバを起動し、次のアドレスにアクセスします.
http://localhost:8080/student-web/jaxws-spring?wsdl
完了!
クライアントの作成
クライアントとサービス側は異なる2つのアプリケーションであるため、本例ではサービス側はTomcatをコンテナとして、クライアントはjettyをコンテナとして使用する
1、サービス側のプラグインを修正し、tomcatを使用する
<!-- cargo tomcat -->
<!-- : -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<container>
<containerId>tomcat6x</containerId>
<home>E:\technology-hqh\soft\server\apache-tomcat-6.0.29</home>
</container>
<configuration>
<!-- -->
<type>standalone</type>
<home>${project.build.directory}/tomcat6x</home>
<properties>
<!-- -->
<cargo.servlet.port>9999</cargo.servlet.port>
</properties>
</configuration>
<deployables>
<deployable>
<type>war</type>
<properties>
<!-- -->
<context>/server</context>
</properties>
</deployable>
</deployables>
</configuration>
</plugin>
2、クライアントの作成開始
基本手順:
jaxws-maven-pluginを使用してwsdlをローカルjavaファイルに変換
springMVCによるプレゼンテーションレイヤの機能
Jaxws-springを使用してJAX-WSとspringを統合し、主にクライアントにendpointサービスオブジェクトを注入します.
maven-jetty-pluginプラグインを使用してjettyをクライアントのサーバとして使用
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hqh.student</groupId>
<artifactId>student-cient-remote</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>student-cient-remote Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.0.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!-- SPRING -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- servlet+jstl+jsp -->
<dependency>
<groupId>servletapi</groupId>
<artifactId>servletapi</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<!-- jaxws-rt :
java.lang.ClassNotFoundException: com.sun.istack.XMLStreamReaderToContentHandler -->
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.3</version>
<!-- activation, java.lang.LinkageError: loader constraint violation-->
<exclusions>
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- jax spring -->
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.8</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<!-- activation-->
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>student-cient-remote</finalName>
<!-- jetty -->
<plugins>
<!-- jetty -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.10</version>
<configuration>
<scanIntervalSeconds>1000</scanIntervalSeconds>
</configuration>
</plugin>
<!-- -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!--jaxws -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.9</version>
<configuration>
<wsdlUrls>
<wsdlUrl>http://localhost:9999/server/jaxws-spring?wsdl</wsdlUrl>
</wsdlUrls>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- beanFactory -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springMVC -->
<servlet>
<servlet-name>srpingMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>srpingMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- spring jax -->
<servlet>
<servlet-name>StudentWsService-WSSpringServlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentWsService-WSSpringServlet</servlet-name>
<url-pattern>/jaxws-spring</url-pattern>
</servlet-mapping>
</web-app>
srpingMVC-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
<!-- -->
<context:component-scan base-package="com.hqh"/>
<!-- -->
<mvc:resources location="/resources/" mapping="/resources/**"/>
<!-- : + + -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
applicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://jax-ws.dev.java.net/spring/core http://jax-ws.dev.java.net/spring/core/spring-jax-ws-core.xsd
http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet/spring-jax-ws-servlet.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.hqh.client"/>
<!-- spring webservice ! -->
<!-- Accessing web services using JAX-WS -->
<bean id="wsService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="com.hqh.student.ws.IStudentWSService"/>
<property name="wsdlDocumentUrl" value="http://localhost:9999/server/jaxws-spring?wsdl"/>
<property name="namespaceUri" value="http://ws.student.hqh.com"/>
<property name="serviceName" value="StudentWSService"/>
<property name="portName" value="studentServicePort"/>
</bean>
<!-- -->
<bean id="client" class="com.hqh.client.ws.controller.ClientController">
<property name="studentWsService" ref="wsService"></property>
</bean>
</beans>
Controller
package com.hqh.client.ws.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.hqh.student.ws.IStudentWSService;
import com.hqh.student.ws.Student;
@Controller
public class ClientController {
/**
* , setters , 2 ,ClientController
* studentWsService NULL, , static webservice
* spring
* ?
*/
private static IStudentWSService studentWsService;
// setters !
public void setStudentWsService(IStudentWSService wsService) {
studentWsService = wsService;
}
@RequestMapping(value="/getStudent",method=RequestMethod.GET)
public String getStudent() {
return "index";
}
@RequestMapping(value="/getStudent",method=RequestMethod.POST)
public String getStudent(String number,Model model) {
Student stu = studentWsService.getStudent(number);
System.out.println(stu);
if(stu==null) {
model.addAttribute("error", " !");
} else {
model.addAttribute(stu);
}
return "index";
}
}
その間に2つの異常に遭遇して、とても苦労してやっと解決しました!
異常1
java.lang.NoClassDefFoundError: com/sun/istack/XMLStreamReaderToContentHandler
at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:227)
at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:296)
at com.sun.xml.ws.encoding.StreamSOAPCodec.decode(StreamSOAPCodec.java:128)
at com.sun.xml.ws.encoding.SOAPBindingCodec.decode(SOAPBindingCodec.java:287)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:171)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:86)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
at com.sun.xml.ws.client.Stub.process(Stub.java:248)
解決策:
jaxws-rtに依存することを増やして、この問題は解決しました!
異常二
java.lang.LinkageError: loader constraint violation: when resolving overridden method "com.sun.xml.ws.message.jaxb.AttachmentMarshallerImpl.addMtomAttachment(Ljavax/activation/DataHandler;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" the class loader (instance of org/mortbay/jetty/webapp/WebAppClassLoader) of the current class, com/sun/xml/ws/message/jaxb/AttachmentMarshallerImpl, and its superclass loader (instance of <bootloader>), have different Class objects for the type javax/activation/DataHandler used in the signature
at com.sun.xml.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:311)
at com.sun.xml.ws.message.AbstractMessageImpl.writeTo(AbstractMessageImpl.java:142)
at com.sun.xml.ws.encoding.StreamSOAPCodec.encode(StreamSOAPCodec.java:108)
at com.sun.xml.ws.encoding.SOAPBindingCodec.encode(SOAPBindingCodec.java:258)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:142)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:86)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
at com.sun.xml.ws.client.Stub.process(Stub.java:248)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
解決策:
衝突を排除し、依存パケットはコンテナ内のjarパケットと衝突し、jaxws-rtとjaxws-springの依存からactivation 1を排除する.1.jar