Spring+Struts2+Dubbo框架下使用webservice接口服务
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配置就能够实现分布式服务调用,也就是说服务提供方(Provider)发布的服务可以天然就是集群服务,比如,在实时性要求很高的应用场景下,可能希望来自消费方(Consumer)的调用响应时间最短,只需要选择Dubbo的Forking Cluster模式配置,就可以对一个调用请求并行发送到多台对等的提供方(Provider)服务所在的节点上,只选择最快一个返回响应的,然后将调用结果返回给服务消费方(Consumer),显然这种方式是以冗余服务为基础的,需要消耗更多的资源,但是能够满足高实时应用的需求。
项目框架使用Spring+Struts2+Dubbo,系统的web层和业务处理层使用dubbo框架分离成2个项目,如test,testcore。
一开始准备使用dubbo原生的web接口服务,但是一番摸索下,发现系统的test和testcore项目交互使用dubbo的免注册直连方式(dubbo:registry address=”N/A”/ ),不知如何额外添加一个外部接口,故曲线救国,引用cxf服务。
webservices服务放在test项目中。
下面是cxf的框架搭建:
pom.xml中jar引用
<!-- cxf -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.14</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.14</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.14</version>
</dependency>
在web.xml里面添加
<!-- cxf -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
项目中添加cxf配置文件,并把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:soap="http://cxf.apache.org/bindings/soap" 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">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint id="authServerService" implementor="#authServerServiceImpl" address="/authServerService" />
</beans>
服务端接口类
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface IAuthServerService {
/** * Description: 返回用户信息 * * @param userId * @param systemId * @param cityIds */
public String queryUserInfoByUserId(
@WebParam(name = "userId") Integer userId,
@WebParam(name = "systemCd") String systemCd);
}
服务端接口实现类
import java.util.HashMap;
import java.util.Map;
import javax.jws.WebService;
import org.apache.cxf.feature.Features;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Transactional;
import com.ai.frame.bean.InputObject;
import com.ai.frame.bean.OutputObject;
import com.ttt.test.webservice.authcxf.IAuthServerService;
@Transactional
@WebService(endpointInterface = "com.ttt.test.webservice.authcxf.IAuthServerService")
@Features(features = "org.apache.cxf.feature.LoggingFeature")
public class AuthServerServiceImpl implements IAuthServerService {
private static final long serialVersionUID = 215925817441980210L;
private Logger logger = Logger.getLogger(AuthServerServiceImpl.class);
@Override
public String queryUserInfoByUserId(Integer userId, String systemCd) {
logger.info("AuthServerServiceImpl--queryUserInfoByUserId:Start");
//TODO
logger.info("AuthServerServiceImpl--queryUserInfoByUserId:End");
return "";
}
}
客户端的测试类
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceClient;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.log4j.Logger;
@WebServiceClient
public class UserPrivilegeClientImpl implements IUserPrivilegeClient{
Logger log = Logger.getLogger(UserPrivilegeClientImpl.class);
public Object[] callWebService(String wsdl, String targetNamespace, String methodName, Object args[]) {
Object[] res = null;
try {
log.info("动态调用webservice开始,wsdl:"+wsdl+",methodName:"+methodName+",args:" + args);
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(wsdl);
if (targetNamespace == null) {
res = client.invoke(methodName, args);
} else {
res = client.invoke(new QName(targetNamespace, methodName), args);
}
} catch (Exception e) {
log.error("动态调用webservice 失败,wsdl:" + wsdl + ",targetNamespace:" + targetNamespace + ",methodName:"
+ methodName + ",args:" + args, e);
// throw new CIServiceException("动态调用webservice 失败");
}
return res;
}
public static void main(String[] args) {
String wsdl = "http://127.0.0.1:8080/test/services/authServerService?wsdl"; //WSDL
String targetNamespace = "http://authcxf.webservice.test.ttt.com/"; //WSDL
String methodName ="queryUserInfoByUserId";
Object params[] = {2929,"RR0001"};
IUserPrivilegeClient client = new UserPrivilegeClientImpl();
Object[] res = client.callWebService(wsdl, targetNamespace, methodName, params);
System.out.println(res.toString());
}
}
至此,这个webservice接口就算完成了,其中的几个类在配置文件中注入的,就不发了