对于web service接口,有着服务端与客户端之分,服务负责编写并暴露接口在服务器上,而客户端,就是携带相关数据与服务端交互,而获取相关数据,然而对于客户端对服务端的访问,也必须通过相关的约束才能访问获取数据,比如客户端携带的登录名及密码啊........而对于客户端数据的拦截怎样实现呢?
首先我们自己编写个接口并暴露
import javax.jws.WebService; @WebService public interface checkLogin { public Boolean login(String name,String pwd); }
接口实现类:
@WebService(endpointInterface="com.azj.service.checkLogin",serviceName="checkLoginImpl") public class checkLoginImpl implements checkLogin { @Override public Boolean login(String name,String pwd) { if("admin".equals(name) && "admin".equals(pwd)){ return true; } return false; } }
这里的webservice注解,发布接口也有两种方式,效果也都一样,我说下:
第一种就是上面的命名方式。
第二种:
编写的接口:
@WebService public interface checkLogin { @WebMethod public Boolean login(String name,String pwd); }
编写的接口实现类:
@WebService public class checkLoginImpl implements checkLogin { @Override public Boolean login(String name,String pwd) { if("admin".equals(name) && "admin".equals(pwd)){ return true; } return false; } }
这两种方式的注解,我想你也看出优劣势了吧!!
我们再说接口的暴露:
public class servicePulish { public static void main(String[] args) { checkLogin cl=new checkLoginImpl(); EndpointImpl el=(EndpointImpl) Endpoint.publish("http://localhost:8080/test", cl); el.getInInterceptors().add(new inchecked());//这里有进出拦截器之分,对于服务端而言,客户端要携带数据进入服务端,所以就是进入拦截器的编写 } }
进入拦截器的编写:
public class inchecked extends AbstractPhaseInterceptor<SoapMessage> { //由于AbstractPhaseInterceptor无无参数构造器,使用继承的方式,需要显示调用父类有参数的构造器 public inchecked() {
//Phase.PRE_PROTOCOL做好准备工作,在调用方法之前进行拦截 super(Phase.PRE_PROTOCOL); } //实现自己的拦截器时,需要实现handleMessage方法。 //handleMessage方法中的形参就是被拦截到的Soap消息 @Override public void handleMessage(SoapMessage ms) throws Fault { Header header = ms.getHeader(new QName("azj"));//获取标志为“azj”的header头,这里必须与客户端的的携带数据的标志header相对应 Element el = (Element) header.getObject(); String name = el.getElementsByTagName("name").item(0).getTextContent(); String pwd = el.getElementsByTagName("pwd").item(0).getTextContent(); //假如要求Header携带了用户名,密码信息 if("admin".equals(name) && "admin".equals(pwd)){ System.out.println("success"); }else System.out.println("fail"); } }
编写的拦截器类inchecked必须继承extends AbstractPhaseInterceptor<SoapMessage>这个类,重写相关方法。而 AbstractPhaseInterceptor<SoapMessage>则是继承的interceptor这个父类而对应获取web service的soap携带的相关数据的信息,而这些信息都放在请求头header里面
客户端代码:
public static void main(String[] args) { CheckLoginImpl cl=new CheckLoginImpl(); CheckLogin lo = cl.getCheckLoginImplPort(); Client client = ClientProxy.getClient(lo); client.getOutInterceptors().add(new outCheck("admin","admin")); //对于客户端而言,就是数据传出的拦截 if(lo.login("admin", "admin")){ System.out.println("登录验证成功"); } }
客户端拦截器:
public class outCheck extends AbstractPhaseInterceptor<SoapMessage> { private String name; private String pwd; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public outCheck(String name,String pwd) { super(Phase.PREPARE_SEND);//在准备发送SOAP消息时启用该拦截器 this.name=name; this.pwd=pwd; } @Override public void handleMessage(SoapMessage ms) throws Fault {
//创建一个标志为“azj”的xml
* <azj> * <nameele >hejingyuan</nameele > * <pwdele >hjy</pwdele > * </azj> List<Header> headers = ms.getHeaders(); Document dom = DOMUtils.createDocument(); Element el = dom.createElement("azj"); Element nameele = dom.createElement("name"); nameele.setTextContent(name); Element pwdele = dom.createElement("pwd"); pwdele.setTextContent(pwd); el.appendChild(nameele); el.appendChild(pwdele); //把el元素包装成Header,并添加到SOAP消息的Header列表中 headers.add(new Header(new QName("azj"), el)); } }