基于SAAJ的客户端

概述


SAAJ - SOAP with Attachments API for JAVA

结构图如下:

正文


1. 如何获取soap请求的关键参数

关键的参数有四个:

  1. xmlns - xml命名空间
    如果你对命名空间没有概念,请参考:w3school - XML命名空间
  2. 服务的地址
  3. service的name
  4. port的name

获取:

  1. 在wsdl文档的root元素的targetNamespace可以获取到xmlns:
  2. 在service元素可以获取其他三个参数

    上图黄色高亮标注了三个地方,分别可以获得service的name,port的name,服务的地址。
    值得一说的是,这里的service的name和wsdl文档root元素的name是相同的,但这只是巧合;这里的才“真的是”,那里的只是“长得像”。

2. 参数声明

/** 服务的地址 */
private static final String ADDRESS = "http://localhost:6666/service/interpret";
/** 目标命名空间 */
private static final String TARGET_NAME_SPACE = "http://service.chapter1.jws.sand.ljl.cn/";
/** service的名称 */
private static final String SERVICE_NAME = "InterpretServiceImplService";
/** port的名称 */
private static final String PORT_NAME = "InterpretServiceImplPort";

3. 创建消息

/**
 * 创建并填充SOAP message.
 * @return
 * @throws SOAPException
 */
private SOAPMessage createMessage() throws SOAPException {
  // 1. 创建message
  SOAPMessage message = MessageFactory.newInstance().createMessage();

  // 2. 获取Envelope
  SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();

  // 3. 获取body
  SOAPBody body = envelope.getBody();

  // 4. 构造interpret元素
  QName qname = new QName(TARGET_NAME_SPACE, "interpret", "ns");

  // 5. 向body中添加元素
  SOAPBodyElement bodyElement = body.addBodyElement(qname);

  // 6. 添加子元素
  bodyElement.addChildElement("num").setValue("112358");

  return message;
}

上述代码的创建结果:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header/>
<SOAP-ENV:Body>

关于QName

QName qname = new QName("http://service.chapter1.jws.sand.ljl.cn/", "interpret", "ns");

上述代码的三个参数,分别表示命名空间、本地名称、前缀。相当于创建了下述的xml元素:

<ns:interpret xmlns:ns="http://service.chapter1.jws.sand.ljl.cn/" />

关于打印SOAPMessage

使用javax.xml.soap.SOAPMessage.writeTo(OutputStream out)可以把消息打印到指定的输出流。

4. 发送消息

/**
 * 发送SOAP message,并返回响应的SOAP message.
 * @param request
 * @return
 * @throws MalformedURLException
 */
private SOAPMessage send(SOAPMessage request) throws MalformedURLException {
  // 1. 根据address、serviceName创建service
  URL url = new URL(ADDRESS);
  QName serviceName = new QName(TARGET_NAME_SPACE, SERVICE_NAME);
  Service service = Service.create(url, serviceName);

  // 2. 使用service,根据portName创建dispatch
  QName portName = new QName(TARGET_NAME_SPACE, PORT_NAME);
  Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
       SOAPMessage.class, Service.Mode.MESSAGE);

  // 3. 发送请求
  SOAPMessage response = dispatch.invoke(request);

  return response;
}

上述代码获得的响应的结果:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Header/>
  <S:Body>
     <ns2:interpretResponse xmlns:ns2="http://service.chapter1.jws.sand.ljl.cn/">
       <chnum>一一二三五八</chnum>
     </ns2:interpretResponse>
  </S:Body>
</S:Envelope>

5. 解析结果

Document doc = response.getSOAPPart().getEnvelope()
       .getBody().extractContentAsDocument();
String result = doc.getElementsByTagName("chnum").item(0)
       .getTextContent();

完整的demo


package cn.ljl.sand.jws.chapter2.client;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import org.junit.Assert;
import org.junit.Test;
import org.w3c.dom.Document;
import cn.ljl.sand.jws.chapter1.service.InterpretService;
/**
 * 基于SAAJ的客户端.<br>
 * 所访问的服务参考{@link InterpretService}.
 *
 * @author lijinlong
 *
 */
public class SAAJClient {
    /** 服务的地址 */
    private static final String ADDRESS = "http://localhost:6666/service/interpret";
    /** 目标命名空间 */
    private static final String TARGET_NAME_SPACE = "http://service.chapter1.jws.sand.ljl.cn/";
    /** service的名称 */
    private static final String SERVICE_NAME = "InterpretServiceImplService";
    /** port的名称 */
    private static final String PORT_NAME = "InterpretServiceImplPort";

    /**
     * 创建并填充SOAP message.
     * @return
     * @throws SOAPException
     */
    private SOAPMessage createMessage() throws SOAPException {
        SOAPMessage message = MessageFactory.newInstance().createMessage();
        SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
        SOAPBody body = envelope.getBody();

        QName qname = new QName(TARGET_NAME_SPACE, "interpret", "ns");
        SOAPBodyElement bodyElement = body.addBodyElement(qname);
        bodyElement.addChildElement("num").setValue("112358");

        return message;
    }

    /**
     * 发送SOAP message,并返回响应的SOAP message.
     * @param request
     * @return
     * @throws MalformedURLException
     */
    private SOAPMessage send(SOAPMessage request) throws MalformedURLException {
        URL url = new URL(ADDRESS);
        QName serviceName = new QName(TARGET_NAME_SPACE, SERVICE_NAME);
        Service service = Service.create(url, serviceName);
        QName portName = new QName(TARGET_NAME_SPACE, PORT_NAME);
        Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
                SOAPMessage.class, Service.Mode.MESSAGE);
        SOAPMessage response = dispatch.invoke(request);
        return response;
    }

    @Test
    public void test() throws SOAPException, IOException {
        SOAPMessage request = createMessage();
        request.writeTo(System.out);

        SOAPMessage response = send(request);
        response.writeTo(System.out);

        Document doc = response.getSOAPPart().getEnvelope()
               .getBody().extractContentAsDocument();
        String result = doc.getElementsByTagName("chnum").item(0)
               .getTextContent();
        Assert.assertEquals("一一二三五八", result);
    }
}

来自为知笔记(Wiz)

时间: 2024-10-07 04:42:56

基于SAAJ的客户端的相关文章

HAProxy基于cookie实现客户端会话保持

HAProxy基于cookie实现客户端会话保持 使用ip_hash时,如果有众多用户使用相同的公网地址去访问同一个服务时,由于这些用户所使用的公网IP都为同一个,HAproxy就会把他们调度到同一后端的服务器,由此可能造成后天的单台服务器的压力过大,因此需要其他的方法来进行调度.HAProxy可以实现插入一层cookie,当用户第一次访问会查看是否有cookie,如果没有就在响应报文中插入以程cookie返回给客户端,当用户再次访问就会根据cookie来调度请求.lvs和nginx无法实现 c

基于UDP的客户端和服务器端的代码设计

实验平台 linux 实验内容 编写UDP服务器和客户端程序,客户端发送消息,服务器接收消息,并打印客户端的IP地址和端口号. 实验原理 UDP是无需连接的通信,其主要实现过程如下: 同样,我们可以按照上一篇博客:基于TCP的客户端和服务器端的代码设计 的办法,将服务器代码分成两部分,一个是初始化,一个是收发数据.但是UDP服务器初始化较为简单,也可以直接写在main函数里. UDP和TCP在读写数据上较为不同的是,sendto()和recvfrom(),这两个函数较为复杂.通过man手册查询得

基于TCP的客户端、服务器端socket编程

一.实验目的 理解tcp传输客户端服务器端通信流程 二.实验平台 MAC OS 三.实验内容 编写TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址.端口号,并向客户端发送字符串. 四.实验原理 使用TCP套接字编程可以实现基于TCP/IP协议的面向连接的通信,它分为服务器端和客户端两部分,其主要实现过程如下 服务器端代码: 1 #include "iostream" 2 #include "netdb.h" 3 #inclu

基于Git项目管理客户端SourceTree的免注册安装及远程连接方法

作为程序员,不可避免的要在github上查询代码,而在企业项目中,为了使得项目好管理需要使用项目管理客户端,所以接下来详细讲解一下基于git的sourceTree在windows系统下的安装及与GitHub上的账号进行远程连接同步更新的过程. 由于sourceTree的安装过程中有内嵌git的安装,所以我们不需要单独到git的官方网站上去下载安装git,直接通过sourceTree的安装来安装git. 一.sourcetree的免注册安装过程  首先,下载windows版本的sourceTree

基于UltraVNC实现客户端远程控制

前言 一般远程就直接用windows自带的,配置好动态IP花生壳,在任何地方都可以连回机子.最近项目里遇到这么个情况,需要快速接入远程控制功能,客户机的IP每次都会变,并且都是在外网,这样,就必须使用带有中转服务器的远程控制,网上查了一下有TightVNC和UltraVNC两个比较好的开源远程控制项目. 可惜TightVNC目前中转服务器端还在开发,下个版本可能才有. 所以果断选择使用UltraVNC! 介绍 VNC(Virtual Network Computing),为一种使用RFB协定的屏

基于socket的客户端和服务端聊天机器人

服务端代码如下: using System;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Windows.Forms; namespace Client{ public partial class Form1 : Form { public Form1() { InitializeComponent(); //对 Windows 窗体控件进行线程安全调

基于socket的客户端和服务端聊天简单使用 附Demo

功能使用 服务端 分离一个不停接受客户端请求的线程 接受不客户端请求的线程中,再分离就收消息的线程 几大对象分别是 IPEndPoint IP终结点 服务端Socket,绑定终结点Bind,启动监听Listen(100) 100代表的监听请求队列的长度 接受请求的客户端Socket,接受消息 Receive 接受的字节与文本间的互转 客户端 只有一个分离接受服务端发送消息的线程 几大对象 客户端Socket 客户端连接Connect 客户端发送 客户端接受 接受的字节与文本间的互转 附Demo下

基于socket.io客户端与服务端的相互通讯

socket.io是对websocket的封装,用于客户端与服务端的相互通讯.官网:https://socket.io/. 下面是socket.io的用法: 1.由于使用express开的本地服务,先下载相关依赖 cnpm install express socket.io 2.服务端代码 const express = require("express"); const io = require("socket.io"); const app = express(

python网络编程(基于twisted的客户端编程)

[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] python的twisted比较有意思,既可以做server方面的编程,也可以做client方面的编程.关于这方面的编程,最简单的例子就是echo. client 代码如下, #!/usr/bin/python from twisted.internet.protocol import Protocol, ClientFactory from sys import stdout from tw