一、先来说webservice服务端
结构图如下:
1.添加jar包(放入WEB_INF下的lib目录)(如图)
2.编写一个需要发布的接口(IHelloWebService)
package com.webservice;
import javax.jws.WebService;
@WebService
public interface IHelloWebService {
/**
* example
* @param message
* @return
*/
public String example(String message);
}
3.对接口的实现
package com.webservice;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
@WebService(endpointInterface="com.webservice.IHelloWebService")
public class HelloWebServiceImpl implements IHelloWebService {
public String example(String message) {
//处理逻辑
return "Webservice 服务器返回的信息:"+message;
}
}
4.验证头的服务端(Handler)
package com.webservice.checkclient;
import org.apache.log4j.Logger;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.exchange.InMessage;
import org.codehaus.xfire.fault.XFireFault;
import org.codehaus.xfire.handler.AbstractHandler;
import org.jdom.Element;
import org.jdom.Namespace;
/**
* Server端的认证模块,回调处理模块
* @author Administrator
*/
public class ServerAuthenticationHandler extends AbstractHandler {
private static final Logger log = Logger.getLogger(ServerAuthenticationHandler.class);
public void invoke(MessageContext context) throws Exception {
if (context.getInMessage().getHeader() == null) {
throw new org.codehaus.xfire.fault.XFireFault("请求必须包含验证信息",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
Element token = context.getInMessage().getHeader().getChild(
"AuthenticationToken");
if (token == null) {
throw new org.codehaus.xfire.fault.XFireFault("请求必须包含身份验证信息",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
String username = token.getChild("Username").getValue();
String password = token.getChild("Password").getValue();
/**
* 检查用户名密码是否正确
*/
PasswordAuthenticationManager manager=new PasswordAuthenticationManager();
if(!manager.verify(username,password))
throw new XFireFault("用户名密码错误,请重新确认",
XFireFault.SENDER);
}
}
5.编写验证用户名密码的具体方法
package com.webservice.checkclient;
public class PasswordAuthenticationManager {
public boolean verify(String username,String password){
boolean flag=false;
if("aaa".equals(username)&&"111".equals(password)){
flag=true;
}
return flag;
}
}
6.写services.xml文件(在WebRoot下META-INF新建xfire文件夹放入services.xml文件)
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<service xmlns="http://xfire.codehaus.org/config/1.0">
<name>HelloWebService</name>
<serviceClass>
com.webservice.IHelloWebService
</serviceClass>
<implementationClass>
com.webservice.HelloWebServiceImpl
</implementationClass>
<!--注册监听处理器(server端的handler)-->
<inHandlers>
<handler handlerClass="com.webservice.checkclient.ServerAuthenticationHandler"></handler>
</inHandlers>
<style>wrapped</style>
<use>literal</use>
<scope>application</scope>
</service></beans>
7.配置web.xml
<?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">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>XFireServlet</servlet-name>
<servlet-class>
org.codehaus.xfire.transport.http.XFireConfigurableServlet
</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
8.server端的main方法(测试是否发布成功)
package com.webservice;
import javax.xml.ws.Endpoint;
public class TestMain {
public static void main(String[] args){
//参数1:绑定服务的地址
//参数2:提供services的实例
Endpoint.publish("http://127.0.0.1:8080/webServer/services/HelloWebService", new HelloWebServiceImpl());
//url的services是在web.xml中配置的路径
//url的HelloWebService是与name(services.xml)对应的
System.out.println("WebService服务启动");
}
}
9.在浏览器地址栏输入http://127.0.0.1:8080/webServer/services/HelloWebService?wsdl(显示xml格式的document则发布成功)
二、客户端调用
1.客户端的验证handler
package com.webservice;
import org.apache.log4j.Logger;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.handler.AbstractHandler;
import org.jdom.Element;
/**
* @author Administrator
*/
public class ClientAuthHandler extends AbstractHandler {
private static final Logger log = Logger.getLogger(ClientAuthHandler.class);
private String username;
private String password;
public void invoke(MessageContext arg0) throws Exception {
Element el = new Element("header");
arg0.getOutMessage().setHeader(el);
Element auth = new Element("AuthenticationToken");
Element username_el = new Element("Username");
username_el.addContent(username);
Element password_el = new Element("Password");
password_el.addContent(password);
auth.addContent(username_el);
auth.addContent(password_el);
el.addContent(auth);
}
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;
}
}
2.通过Web服务端提供的接口来创建客户端
package com.webservice;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.codehaus.xfire.client.Client;
import org.codehaus.xfire.client.XFireProxy;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
/**
* 通过Web服务端提供的接口来创建客户端
*/
public class ClientFromInterface {
public static void main(String[] args)throws Exception{
Service serviceModel = new ObjectServiceFactory().create(IHelloWebService.class);
//访问的地址
String serviceURL = "http://127.0.0.1:8080/webServer/services/HelloWebService";
ClientAuthHandler wscname = new ClientAuthHandler();
wscname.setUsername("aaa");
wscname.setPassword("111");
//为XFire获得一个代理工厂对象
XFireProxyFactory factory = new XFireProxyFactory();
//通过proxyFactory,使用服务模型serviceModel和服务端点URL(用来获得WSDL)
//得到一个服务的本地代理,这个代理就是实际的客户端
IHelloWebService client = (IHelloWebService)factory.create(serviceModel, serviceURL);
XFireProxy proxy = (XFireProxy) Proxy.getInvocationHandler(client);
Client clientOne = proxy.getClient();
clientOne.addOutHandler(wscname);
String serviceResponse = client.example("SayHello");
System.out.println(serviceResponse);
}
}
正常输出,调用成功
———————————————-END
Attention:(总结一下遇到的几个问题)
1.如果出现class path resource [META-INF/xfire/services.xml] cannot be opened because it does not exist
修改方法:把META-INF文件夹整个copy到工程的build的classes目录下。
2.出现异常org.springframework.beans.factory.BeanDefinitionStoreException: Unrecognized xbean namespace mapping: http://XFire.codehaus.org/config/1.0 (两种修改方案)
1、
<beans xmlns="http://xfire.codehaus.org/config/1.0>
<service">
</beans>
换为(以下的代码为本文的写法)
<beans>
<service xmlns="http://xfire.codehaus.org/config/1.0">
</beans>
2、 xmlns=”http://xfire.codehaus.org/config/1.0 “> 应该是全部小写。
3、Caused by: org.codehaus.xfire.XFireRuntimeException: Couldn’t create type for property authResRoleId on class com.ultrapower.ams.service.resaccount.appaccimpl.AppResAccount: Cannot create mapping for java.util.Set, unspecified component type for interface java.util.Set
解决办法:
webservice对外接口IHelloWord的方法参数只能是通用类型,(String,Int等类型)
(以上demo若有相似之处,是搜索得来,谢谢支持)