我能够使用 javax.xml.soap.* 向 Web 服务发送请求,我想隐藏代码以使用 webServiceTemplate。
webServiceTemplate 覆盖 java.xml.soap。如果没有我做对了吗?鉴于我需要连接到 20 个网络服务。它唯一的服务是findEvents,如下:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://ticketmaster.productserve.com/v2/soap.php" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<soap:findEvents soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<request xsi:type="soap:Request">
<!--You may enter the following 7 items in any order-->
<apiKey xsi:type="xsd:string">?</apiKey>
<country xsi:type="xsd:string">?</country>
<resultsPerPage xsi:type="xsd:int">?</resultsPerPage>
<currentPage xsi:type="xsd:int">?</currentPage>
<sort xsi:type="soap:Request_Sort">
<!--You may enter the following 2 items in any order-->
<field xsi:type="xsd:string">?</field>
<order xsi:type="xsd:string">?</order>
</sort>
<filters xsi:type="soap:ArrayOfRequest_Filter" soapenc:arrayType="soap:Request_Filter[]"/>
<updatedSince xsi:type="xsd:string">?</updatedSince>
</request>
</soap:findEvents>
</soapenv:Body>
</soapenv:Envelope>
我的代码如下:
try {
SOAPConnectionFactory soapConnectionFactory =
SOAPConnectionFactory.newInstance();
SOAPConnection connection =
soapConnectionFactory.createConnection();
MessageFactory factory =
MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPHeader header = message.getSOAPHeader();
header.detachNode();
SOAPBody body = message.getSOAPBody();
SOAPFactory soapFactory =
SOAPFactory.newInstance();
Name bodyName;
bodyName = soapFactory.createName("findEvents",
"xsd", "http://ticketmaster.productserve.com/v2/soap.php");
SOAPBodyElement getList =
body.addBodyElement(bodyName);
Name childName = soapFactory.createName("findEvents");
SOAPElement eventRequest = getList.addChildElement(childName);
childName = soapFactory.createName("apiKey");
SOAPElement apiKey = eventRequest.addChildElement(childName);
apiKey.addTextNode("MYAPI");
childName = soapFactory.createName("country");
SOAPElement cid = eventRequest.addChildElement(childName);
cid.addTextNode("UK");
message.writeTo(System.out); //show message details
URL endpoint = new URL("http://ticketmaster.productserve.com/v2/soap.php");
SOAPMessage response =
connection.call(message, endpoint);
connection.close();
//SOAPBody soapBody = response.getSOAPBody();
SOAPMessage sm = response;
System.out.println("Response:");
ByteArrayOutputStream out = new ByteArrayOutputStream();
sm.writeTo(out);
String validSoap = "<?xml version=\"1.0\"?> " + out.toString();
System.out.println("It is ValidSoap: " + validSoap); //ValidSoap message
SAXBuilder builder = new SAXBuilder();
Reader in = new StringReader(validSoap); //reading character stream
Document doc = null; //empty jDom document is instantiated
doc = builder.build(in); //build the jDom document
Element root = doc.getRootElement(); //Envelope
List allChildren = root.getChildren(); //list of all its child elements
System.out.println("Root is:" + ((Element) allChildren.get(0)).getName());
listChildren(root);
} catch (Exception ex) {
ex.printStackTrace();
}
新代码
webServiceTemplate.sendSourceAndReceiveToResult
("http://ticketmaster.productserve.com/v2/soap.php",source, result);
@XmlRootElement
public class FindEvents {
@XmlElement
Request request;
public Request getRequest() {
return request;
}
public void setRequest(Request request) {
this.request = request;
}
}
@XmlSeeAlso(SortTicket.class)
public class Request {
@XmlElement
String apiKey;
@XmlElement
String country;
@XmlElement
int resultsPerPage;
@XmlElement
int currentPage;
@XmlElement(name = "Sort")
SortTicket sort;
@XmlElement
String[] filters;
@XmlElement
String updatedSince;
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public int getResultsPerPage() {
return resultsPerPage;
}
public void setResultsPerPage(int resultsPerPage) {
this.resultsPerPage = resultsPerPage;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public SortTicket getSort() {
return sort;
}
public void setSort(SortTicket sort) {
this.sort = sort;
}
public String[] getFilters() {
return filters;
}
public void setFilters(String[] filters) {
this.filters = filters;
}
public String getUpdatedSince() {
return updatedSince;
}
public void setUpdatedSince(String updatedSince) {
this.updatedSince = updatedSince;
}
}
public class SortTicket {
@XmlElement
String field;
@XmlElement
String order;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
}
最佳答案
由于您已经生成了带有 Jaxb 注释的 DTO 类,您可以创建编码器、解码器并创建 DTO 类的对象(SortTicket、Request、FindEvents) 并直接发送对象而不是使用 xml 请求
webServiceTemplate.marshalSendAndReceive(findEvents);
你必须配置这样的东西。
创建编码器
<oxm:jaxb2-marshaller id="marshaller" contextPath="com.yourcontextpath" />
创建网络服务模板
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="marshaller" ref="marshaller" />
<property name="unmarshaller" ref="marshaller" />
<property name="defaultUri"
value="http://ticketmaster.productserve.com/v2/soap.php" />
</bean>
在你想发送soap请求的某个类的方法中,使用@Autowired
webServiceTemplate
@Autowired
private WebServiceTemplate webServiceTemplate;
public void sendSampleSoapRequest() {
SortTicket sortTicket=new SortTicket();
// set its values
Request request=new Request();
//set its values
request.setSort(sortTicket);
FindEvents findEvents=new FindEvents();
setRequest(request)
Object response=webServiceTemplate.marshalSendAndReceive(findEvents);
}
marshalSendAndReceive 消息使用 Jaxb 编码器将您的对象(标有 JaxB 注释)转换为 xml。因此,您的 findEvents 对象将被转换为它的 xml。
关于你的第二点
使用 webServiceTemplate 优于 java.xml.soap 的优势。 :您不必手动创建那些 SOAPElement,您只需创建一个对象并发送它,而不是手动处理它的大代码。
由于您必须连接到 20 个不同的 Web 服务,因此您可以更轻松地创建 DTO 对象并直接发送它们。您可能需要稍微修改我上面的示例。可能会删除默认 uri
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="marshaller" ref="marshaller" />
<property name="unmarshaller" ref="marshaller" />
</bean>
在发送请求时给出 URI 请求
Object response=webServiceTemplate.marshalSendAndReceive(uri,object);
用于发送到多个服务器
Object response1=webServiceTemplate.marshalSendAndReceive(uri1,object);
Object response1=webServiceTemplate.marshalSendAndReceive(uri2,object)
uri1 和uri2 可以是不同的soap 服务如果你没有wsdl 你可以用这个方法发送xml
sendSourceAndReceiveToResult(uri1,source, result);
sendSourceAndReceiveToResult(uri2,source, result);
在 send 方法中发送 uri 会覆盖默认 URI
关于java - 如何在 Spring 中构建 SOAP 客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30845148/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.