WebService之soap类型的服务和rest类型的服务
1.引言
WebService顾名思义就是web服务,web服务主要有两种,一种是基于soap类型的服务,一种是基于rest类型的服务,其中soap类型的服务有两种版本,一种是soap1.1版本,一种是soap1.2版本,soap服务类型的数据是xml数据格式的,而rest服务的数据类型是json格式的。
2.什么是WSDL?
wsdl(网络服务描述语言)是Web Service的描述语言,也就是说wsdl文件是soap的使用说明书。在学习soap之前,认识WSDL是非常有必要的,只有能看懂WSDL文件,我们才可以去调用soap类型的Web服务,下面是一个非常简单的wsdl文件。
3.在WSDL文件中我们可以获得什么信息?
- soap服务的名称
- soap服务的地址
- soap服务暴露的方法
- soap服务方法的参数
- soap服务方法参数的类型和相应的返回值执行
4.利用Java发布soap服务
接下来我们利用Java发布一个soap类型的服务,在Java JDK1.6版本以后,我们可以通过Endpoint
来发布一个soap服务,代码如下:
package com.skd.service; import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.Endpoint; //必须要加注释
@WebService
public class Hello {
public String sayHello(String name){
return "hello " + name;
}
public static void main(String[] args) {
//服务的地址
String address = "http://localhost:8080/hello";
Hello implementor = new Hello();
//发布服务,第一个参数是服务的地址,第二个参数是发布出去服务的方法
Endpoint.publish(address, implementor);
}
}
5.利用JDK注释控制WSDL文件
代码如下:
package com.skd.service; import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.Endpoint; @WebService(targetNamespace="http://com.wpx",serviceName="WPXService")
public class Hello {
//提供一个合法的web方法
@WebMethod(operationName="myMethod")
@WebResult(name="myRet")
public String sayHello(
@WebParam(name="name")
String name){
return "hello " + name;
}
//排除当前方法
@WebMethod(exclude=true)
public String sayHi(String name){
return "hi " + name;
}
public static void main(String[] args) {
String address = "http://localhost:8080/hello";//服务的发布地址
Hello implementor = new Hello();//提供服务的实例
Endpoint.publish(address, implementor);//发布服务
}
}
6.1利用wsimport进行soap服务进行调用
wsimport原理是根据wsdl文件生成本地代理。
- 首先我们使用wsimport命令生成java文件(需要安装JDK)
wsimport -s ./ http://localhost:8080/hello?wsdl
//如果指定输出的包名代码为:
wsimport -s ./ -p com.skd.client.wsimport http://localhost:8080/hello?wsdl
//打jar包的命令:(将当前的com文件夹打成ws.jar)
jar cvf ws.jar ./com
- 创建一个方法,调用Web服务,代码如下
import wpx.com.Hello;
import wpx.com.WPXService; public class APP {
public static void main(String[] args) {
WPXService service=new WPXService();
Hello h=service.getHelloPort();
String result=h.myMethod("wpx");
System.out.println(result);
} }
总结:wsimport调用web服务的java代码是有规律的,总共分为三步:
- 创建服务名对象
- 通过服务名获得接口对象(一般是getXXX,其中XXX代表服务名的port属性)
- 通过接口对象调用服务方法
6.2通过UrlConnection访问Soap服务
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL; /**
* 使用UrlConnection方式调用WebService服务
*
*/
public class APP {
public static void main(String[] args) throws Exception {
// WebService服务的地址
URL url = new URL("http://localhost:8080/hello");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//是否具有输入参数
conn.setDoInput(true);
//是否输出输入参数
conn.setDoOutput(true);
//发POST请求
conn.setRequestMethod("POST");
//设置请求头(注意一定是xml格式)
conn.setRequestProperty("content-type", "text/xml;charset=utf-8"); // 构造请求体,符合SOAP规范(最重要的)
String requestBody = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:q0=\"http://com.wpx\" "
+ "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ "<soapenv:Body>"
+ "<q0:myMethod>"
+ "<name>wpx</name>"
+ "</q0:myMethod>"
+ "</soapenv:Body>"
+ "</soapenv:Envelope>"; //获得一个输出流
OutputStream out = conn.getOutputStream();
out.write(requestBody.getBytes()); //获得服务端响应状态码
int code = conn.getResponseCode();
StringBuffer sb = new StringBuffer();
if(code == 200){
//获得一个输入流,读取服务端响应的数据
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0; while((len = is.read(b)) != -1){
String s = new String(b,0,len,"utf-8");
sb.append(s);
}
is.close();
} out.close();
System.out.println("服务端响应数据为:"+sb.toString()); }
}
6.3利用JDK的Service方法
在前两种方法中,第一种方案生成的代码非常多,第二种方案服务器返回的数据需要我们来解析,都不是非常的完美,我们可以使用第三种方法,生成的代码不是非常的多,对于服务器返回的数据也不需要我们自己来解析,过程如下。
- 首先我们使用wsimport生成本地代码(但是我们只把接口文件拷贝到我们项目中来)
import java.net.MalformedURLException;
import java.net.URL; import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class APP {
public static void main(String[] args) throws Exception {
String wsdlUrl = "http://localhost:8080/hello?wsdl";
//QName,第一个参数是服务的命名空间,第二个参数是服务的名称
Service service = Service.create(new URL(wsdlUrl), new QName("http://com.wpx", "WPXService"));
//QName,第一个参数是服务的命名空间,第二个参数是得到接口的Port
Hello port = service.getPort(new QName("http://com.wpx","HelloPort"), Hello.class);
String ret = port.myMethod("wpx");
System.out.println(ret);
}
}
QName qname = new QName("http://...",
"Service");
Service service = new Service(Url,qname);
ServiceSoap sop =service.getServiceSoap();
String res = sop.docUpload(bs, clntnum+"_"+strformat.format(date)+"_"+i + ".jpg");
res = res.replace("\\", "/");
注:QName
api:https://www.oschina.net/uploads/doc/flex-doc-3.2/QName.html
1.来历:qname是qualified name 的简写
2.构成:由名字空间(namespace)前缀(prefix)以及冒号(:),还有一个元素名称构成
3.举例:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
version="1.0">
<xsl:template match="foo">
<hr/>
</xsl:template>
</xsl:stylesheet>
xsl是名字空间前缀,template是元素名称,xsl:template 就是一个qname
4.总结:qname无非是有着特定格式的xml元素,其作用主要是增加了名字空间,比如有同样的元素名称,而名字空间不同的情况。
7.CXF发布服务
7.1 CXF发布SOAP类型的服务-无接口(http://localhost:8080/hello)
- 首先引用cxf的jar包
- 利用CXF发布没有接口的SOAP服务
package com.skd.service; import javax.jws.WebService; @WebService
public class Hello {
public String sayHello(String name){
System.out.println("sayHi called...");
return " hello " + name;
} }
package com.skd.soap; import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import com.skd.service.Hello; public class JaxWsBean { /**
* 使用JaxWsServerFactoryBean发布CXF的WebService服务
*/
public static void main(String[] args) {
//使用JaxWsServerFactoryBean发布服务,需要在类上加入@WebService注解,
//如果不加,当前类中的方法都不能被发布为web方法
JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();
//发布服务的地址
bean.setAddress("http://localhost:8080/hello");
//因为没有接口,所以
bean.setServiceClass(Hello.class);
//发布服务的实现类
bean.setServiceBean(new Hello());
//发布服务
bean.create();
} }
7.2 CXF发布SOAP类型的服务-有接口(服务地址:”http://localhost:8080/hello“)
接口:
package com.skd.service;
@WebService
public interface IHi {
public String sayHi(String name);
}
实现类:
package com.skd.service; public class HiImpl implements IHi { @Override
public String sayHi(String name) {
return name+"Hi";
} }
发布服务:
package com.skd.soap.impl; import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import com.skd.service.Hello;
import com.skd.service.HiImpl;
import com.skd.service.IHi; public class JaxWsBean { /**
* 使用JaxWsServerFactoryBean发布CXF的WebService服务
*/
public static void main(String[] args) {
//使用JaxWsServerFactoryBean发布服务,需要在类上加入@WebService注解,
//如果不加,当前类中的方法都不能被发布为web方法
JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();
//发布服务的地址
bean.setAddress("http://localhost:8080/hello");
//接口类型
bean.setServiceClass(IHi.class);
//接口的实现类
bean.setServiceBean(new HiImpl());
//发布服务
bean.create();
} }
7.3.cxf发布rest服务(服务地址:http://localhost:8080/hello/*)
创建Person类(必须实现Serializable接口)
package com.skd.rest.service; import java.io.Serializable; public class Person implements Serializable{ private static final long serialVersionUID = 1L;
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} }
接口:
package com.skd.rest.service; import java.util.List; import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; @Produces( { MediaType.APPLICATION_JSON })
public interface IPerson {
@GET//当前方法可以通过GET方式访问
@Path("hello/{name}")//当前方法的访问路径
public Person getPerson(@PathParam("name") String name);//将id获得赋予方法 }
实现类:
package com.skd.rest.service; public class PersonImpl implements IPerson { @Override
public Person getPerson(String name) {
Person p=new Person();
p.setName(name);
p.setAge(11);
return p;
} }
发布服务(注意必须添加序列化类此处用的是JacksonJsonProvider
):
package com.skd.rest.server;
import java.util.ArrayList;
import java.util.List;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import com.skd.rest.service.PersonImpl;
public class JaxWsBean { /**
* 使用JaxWsServerFactoryBean发布CXF的WebService服务
*/
public static void main(String[] args) {
//注意发布rest服务的类为JAXRSServerFactoryBean
JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean();
//发布服务的地址
bean.setAddress("http://localhost:8080");
bean.setResourceClasses(PersonImpl.class);
List<Object> list=new ArrayList<Object>();
//必须添加,用于序列化person类为json对象
list.add(new JacksonJsonProvider());
bean.setProviders(list);
//发布服务
bean.create();
System.out.println("web服务");
} }
8.CXF与Web程序的整合
8.1 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>web</groupId>
<artifactId>cxf</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>cxf Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cxf.version>3.1.9</cxf.version>
<jackson.version>1.9.13</jackson.version>
<spring.version>4.0.5.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--cxf所需要的jar包-->
<!--cxf-rt-frontend-jaxws 对soap服务的支持-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<!--cxf-rt-frontend-jaxrs 对rest服务的支持-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
<!-- 用于rest服务序列化对象-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>${jackson.version}</version>
</dependency>
<!--用于跨域的jar包-->
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>cxf</finalName>
</build>
</project>
8.2 web.xml文件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Set-Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<!--允许跨域的路径,这里只允许我们发布的Web服务跨域-->
<url-pattern>/ws/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>classpath:cxf.xml</param-value>
</init-param>
</servlet>
<!--web服务的地址-->
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping> </web-app>
8.3 SOAP服务的接口,类,实体类
//实体类
public class User {
private String username;
private String password; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
}
} //接口
@WebService
public interface UserService {
public User getUser(String name);
} //接口实现类
public class UserServiceImpl implements UserService{
public User getUser(String name) {
User u=new User();
u.setUsername(name);
u.setPassword("123456");
return u;
}
}
8.4 rest服务的实体类,接口,接口的实现类
//实体类(注意要实现接口Serializable)
public class Person implements Serializable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
} //接口
@Produces( {MediaType.APPLICATION_JSON })
public interface PersonService {
@GET
@Path("/person/{name}")
public Person getPerson(@PathParam("name") String name);
@GET
@Path("/persons")
public List<Person> getPersons();
} //实现类
public class PersonServiceImpl implements PersonService{
public Person getPerson(String name) {
Person p=new Person();
p.setName(name);
p.setAge(100);
return p;
} public List<Person> getPersons() {
List<Person> persons=new ArrayList<Person>();
Person p1=new Person();
p1.setName("wpx");
p1.setAge(100);
persons.add(p1);
Person p2=new Person();
p2.setName("zlr");
p2.setAge(100);
persons.add(p2);
return persons;
}
}
8.5 CXF的配置文件(cxf.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:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
">
<!--
id:当前服务的唯一标识 address:当前服务对应的请求url serviceClass:接口类型
-->
<jaxws:server id="soapuser" address="/user"
serviceClass="com.skd.service.UserService">
<jaxws:serviceBean>
<bean class="com.skd.service.impl.UserServiceImpl" />
</jaxws:serviceBean>
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
</jaxws:inInterceptors>
</jaxws:server>
<!-- 发布一个Restful方式的WebService服务 -->
<bean id="personServiceImpl" class="com.skd.service.impl.PersonServiceImpl"></bean>
<jaxrs:server id="personService" address="/p">
<jaxrs:serviceBeans>
<ref bean="personServiceImpl" />
</jaxrs:serviceBeans>
<!--提供序列化为json数据的实现类-->
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"></bean>
</jaxrs:providers>
<jaxrs:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
</jaxrs:outInterceptors>
</jaxrs:server>
</beans>
9.CXF与spring的整合
所实现的功能有:
- 将Person,PersonService,PersonServiceImpl发布为Rest类型的服务
- 将User ,UserService,UserServiceImpl发布为Soap类型的服务
- 允许我们的Web服务可以跨域请求
9.1POM.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>spring</groupId>
<artifactId>cxf</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>cxf Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cxf.version>3.1.9</cxf.version>
<jackson.version>1.9.13</jackson.version>
<spring.version>4.1.9.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- CXF -->
<!--cxf-rt-frontend-jaxws支持soap类型服务-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<!--cxf-rt-frontend-jaxrs支持rest服务-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<!--用于跨域的jar包-->
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>1.7</version>
</dependency>
<!-- 用于序列化json服务 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>${jackson.version}</version>
</dependency>
<!--测试框架-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>cxf</finalName>
</build>
</project>
9.2web.xml文件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 通过上下文参数指定spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!--用于设置跨域的拦截器-->
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<!--允许哪一些客户端跨域-->
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Set-Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CORS</filter-name>
<!--允许跨域的路径,这里只允许我们发布的Web服务跨域-->
<url-pattern>/ws/*</url-pattern>
</filter-mapping>
<!-- 配置spring提供的上下文载入器监听器,当项目启动时加载spring配置文件,初始化spring工厂 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
<!--springmvc的配置-->
</web-app>
9.3soap接口,实现类,实体类
public class User {
private String username;
private String password; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
}
} //------------------------
@WebService
public interface UserService {
public User getUser(String name);
} //--------------------------
public class UserServiceImpl implements UserService{
public User getUser(String name) {
User u=new User();
u.setUsername(name);
u.setPassword("123456");
return u;
}
}
9.4rest接口,实现类,实体类
public class Person implements Serializable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
} //interface
@Produces( {MediaType.APPLICATION_JSON })
public interface PersonService {
@POST
@Path("/person/{name}")
public Person getPerson(@PathParam("name") String name);
@POST
@Path("/persons")
public List<Person> getPersons();
} //------------
public class PersonServiceImpl implements PersonService{
public Person getPerson(String name) {
Person p=new Person();
p.setName(name);
p.setAge(100);
return p;
} public List<Person> getPersons() {
List<Person> persons=new ArrayList<Person>();
Person p1=new Person();
p1.setName("wpx");
p1.setAge(100);
persons.add(p1);
Person p2=new Person();
p2.setName("zlr");
p2.setAge(100);
persons.add(p2);
return persons;
}
}
9.5spring-cxf配置文件
<?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:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<!--
id:当前服务的唯一标识 address:当前服务对应的请求url serviceClass:接口类型
-->
<jaxws:server id="soapuser" address="/user"
serviceClass="com.skd.service.UserService">
<jaxws:serviceBean>
<bean class="com.skd.service.impl.UserServiceImpl" />
</jaxws:serviceBean>
</jaxws:server>
<!-- 发布一个Restful方式的WebService服务 -->
<bean id="personServiceImpl" class="com.skd.service.impl.PersonServiceImpl"></bean>
<jaxrs:server id="personService" address="/rest">
<jaxrs:serviceBeans>
<ref bean="personServiceImpl" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<!--提供序列化为json数据的实现类-->
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"></bean>
</jaxrs:providers>
<jaxrs:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
</jaxrs:outInterceptors>
</jaxrs:server>
</beans>
10.SpringBeanAutowiringSupport介绍
Spring为JAX-WS Servlet 终端实现类(SpringBeanAutowiringSupport
)提供了一个方便的基类。为暴露我们的AccountService
,我们扩展了Spring的SpringBeanAutowiringSupport
类并在这里实现了业务逻辑,通常委托这个调用给业务层。我们将简单地在Spring管理的beans的依赖上使用Spring的@Autowired注解。
Spring之集成之Web Services:https://blog.csdn.net/luccs624061082/article/details/40797107
spring-web在version2.5.1的时候,在package org.springframework.web.context.support下加入了一个工具类叫SpringBeanAutowiringSupport,主要用来对Spring Web Application Context之外的类提供@Autowired注入功能。
具体来讲,Servlet中本来不能使用@Autowired注入bean,解决办法是在Servlet的init(ServletConfig)方法中调用SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this),就可以直接使用@Autowired来注入Web Application Context下的一些Service等Bean了。(见下例)
又或者使用Quartz Job的时候,可以在Job类中使用SpringBeanAutowiringSupport,就可以直接直使Spring的bean了。(当然如果Job比较多的话,这种方法还是很不方便,推荐使用SchedulerFactoryBean来集成。另一种更方便的办法是直接将Job集成到Spring Context中,当做一个bean)。
值得注意的是,这个类的作用域是Web Application Context,如果应用中实现的是一个比如ConfigurableApplicationContext,那就不能用该方法来对Servlet或是Job或是其它目标类提供@Autowired。
1. 例子:在Servlet中使用:
public class InitServlet extends HttpServlet { @Autowired
private ServiceA serviceA; public void init(ServletConfig config) throws ServletException {
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
assertNotNull("Service should be injected.", serviceA);
} // Omitted doGet(req, res), doPost(req, res);
}
2. 例子:在Quartz Job中使用:
public class DumpJob implements Job { @Autowired
private ServiceA serviceA; public void execute(JobExecutionContext context) throws JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
assertNotNull("Service should be injected.", serviceA);
}
}
3. SpringBeanAutowiringSupport源码分析:
/**
* Process {@code @Autowired} injection for the given target object,
* based on the current web application context.
* <p>Intended for use as a delegate.
* @param target the target object to process
* @see org.springframework.web.context.ContextLoader#getCurrentWebApplicationContext()
*/
public static void processInjectionBasedOnCurrentContext(Object target) {
Assert.notNull(target, "Target object must not be null");
WebApplicationContext cc = ContextLoader.getCurrentWebApplicationContext();
if (cc != null) {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(cc.getAutowireCapableBeanFactory());
bpp.processInjection(target);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Current WebApplicationContext is not available for processing of " +
ClassUtils.getShortName(target.getClass()) + ": " +
"Make sure this class gets constructed in a Spring web application. Proceeding without injection.");
}
}
}
从方法第2行可以看出通过ContextLoader拿到当前的WebApplicationContext对象,再通过AutowiredAnnotationBeanPostProcessor类来解决当前传入的目标class的@Autowired注入能力。
(AutowiredAnnotationBeanPostProcessor在Spring2.5随着Annotation功能的扩展而增加的,我们平时用context namepace的标签<context:component-scan>时,Spring会默认生成注册AutowiredAnnotationBeanPostProcessor类来帮助解析@Autowired @Value @Inject等标签。)
4. 使用另一个工具类WebApplicationContextUtils来获取Service Bean:
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
ServiceA ServiceA = context.getBean(ServiceA.class);
当然这个方法更强大,因为直接拿到WebApplicationContext对象了!
5. 补充WebApplicationContext相关:
对于Web项目,通常使用org.springframework.web.context.ContextLoaderListener,设置属性contextConfigLocation来生成WebApplicationContext。
WebApplicationContext类图(用StarUML画的):
webservice发布使用spring的SpringBeanAutowiringSupport自动装配不了属性
WebService之soap类型的服务和rest类型的服务的更多相关文章
- SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系
SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系 SOA面向服务的软件架构(Service Oriented Architecture) 是一种计算机软件的设计模式,主要应 ...
- webservice、soap、wsdl
搜集了一些关于webservice.soap.wsdl的基本知识,解决工作中遇到的疑问 一 .什么是webservice(用你的话描述webservice)?在什么时候用webservice(webs ...
- Rest webservice 和SOAP webservice
SOAP: 简单对象访问协议(Simple Object Access Protocol,SOAP)是一种基于 XML 的协议,可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP) ...
- WCF分布式开发步步为赢(9):WCF服务实例激活类型编程与开发
.Net Remoting的激活方式也有三种:SingleTon模式.SingleCall模式.客户端激活方式,WCF服务实例激活类型包括三种方式:单调服务(Call Service),会话服务(Se ...
- 响应消息的内容类型 text/html; charset=utf-8 与绑定(application/soap+xml; charset=utf-8)的内容类型不匹配。
问题表述: 响应消息的内容类型 text/html; charset=utf-8 与绑定(application/soap+xml; charset=utf-8)的内容类型不匹配. 说明: 此类问题当 ...
- java动态获取WebService的两种方式(复杂参数类型)
java动态获取WebService的两种方式(复杂参数类型) 第一种: @Override public OrderSearchListRes searchOrderList(Order_Fligh ...
- WebService的web客户端同步、异步、多线程向服务端传入参数的数据交互方式
接着上一章的内容,在上一章中我们知道了如何.net平台下去建立一个WebService,以及同步调用.异步调用.开线程异步调用三种客户端从服务端获取数据的方式,在本章了所要讲的,是如何将客户端的数据, ...
- MySQL服务 - MySQL列类型、SQL模式、数据字典
MySQL列类型的作用: 列类型可以简单理解为用来对用户往列种存储数据时做某种范围"限定",它可以定义数据的有效值(字符.数字等).所能占据的最大存储空间.字符长度(定长或变长). ...
- 第6章 服务模式 Service Interface(服务接口)
Service Interface(服务接口) 上下文 您正在设计企业应用程序,并且需要能够通过网络使用其部分功能.此功能需要能够被各类系统使用,因此互操作性是设计的重要方面.除互操作性之外,可能还需 ...
随机推荐
- 安装nodejs时:The error code is 2503.
在windows下安装nodejs时老是报错: The installer has encountered an unexpected error installing . 有三种方法可以尝试: &q ...
- Python内置函数(42)——hash
英文文档: hash(object)Return the hash value of the object (if it has one). Hash values are integers. The ...
- 隐藏Easy UI 中parent.$.modalDialog 的button
例子: buttons : [ { text : '关闭', handler : function() { parent.$.modalDialog.handler.dialog('close'); ...
- 使用freemaker 导出word 含多张图片,若无图片则显示文本信息
1.使用的Microsoft Office 2007,添加一个无边框的表格,并插入一张图片,最后另存为编码utf-8,一开始保存的word xml格式的,图片的base64编码位于文档最后,暂时没有找 ...
- NHibernate优点和缺点:
NHibernate优点: 1.完全的ORM框架. NHibernate对数据库结构提供了较为完整的封装,它将数据库模式映射为较完全的对象模型,支持封装,继续机制,功能较强大,比一般的ORM灵活性高. ...
- linux下git常用命令
1 安装: sudo apt-get install git 2 创建一个版本库: 新建一个文件夹,进入这个目录之后 git init 3 创建一个版本: git add 文件名或目录 #表示将当前文 ...
- JavaScript实现面向对象
/* js实现面向对象的方法 */ // 1 工厂模型 不推荐 function Person(name , sex , age){ obj = {}; obj.name = name; obj.se ...
- 给定了经纬度的一张my_latlng表,和一个my_grid表,怎么实现my_latlng表回mygrid中的id?
场景: 假设我们拥有一个拥有了一系列经纬度的表my_latlng(lat string,lng string)表,还有一张给定的栅格表my_grid(gridid bigint,centerlng d ...
- dict的update方法
dict = {'Name': 'Zara', 'Age': 7} dict2 = {'Sex': 'female' } dict.update(dict2)输出结果:{'Age': 7, 'Name ...
- jacascript 事件对象event
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 在触发DOM上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息.所有浏览 ...