我正在研究使用SOAP和Java SAAJ将文件发送到Web服务的WilfFly Web应用程序。
我正面临这个错误(在woodstox-core-asl-4.4.0.jar上):
12:02:46,927 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (default task-24)
Interceptor for {http://wscmis.pms.vr.it/}WSChemistry has thrown exception,
unwinding now: org.apache.cxf.binding.soap.SoapFault: Error reading XMLStreamReader.
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '-'
(code 45) in prolog; expected '<' at [row,col {unknown-source}]: [1,1]
这是我调用WS的方法:
public JSONObject invokeWS(String WSURL, String metodo, Map<String,String> params, String namespace){
MessageFactory factory;
StringBuilder sb = new StringBuilder();
JSONObject jsonResult=null;
try {
factory=MessageFactory.newInstance();
SOAPMessage message=factory.createMessage(); //Creo il messaggio SOAP
SOAPPart soapPart=message.getSOAPPart();
SOAPEnvelope envelope=soapPart.getEnvelope(); //Prendo l'envelope e poi il body (dell'header chissenefrega)
envelope.addNamespaceDeclaration("com", namespace); //Metto il namespace nell'envelope, Enrico's style
SOAPHeader header = envelope.getHeader();
header.detachNode();
SOAPBody body=envelope.getBody();
String elemento="com:"+metodo;
QName bodyName=new QName(elemento); //Mi preparo un elemento da mettere nel body
SOAPBodyElement bodyElement=body.addBodyElement(bodyName);
for(Map.Entry<String, String> entry : params.entrySet()){
if( !entry.getKey().equals("filedocpms") && !entry.getKey().equals("ctype") && !entry.getKey().equals("nomefile")) { //Se sono attributi che non hanno a che fare con l'allegato li metto normalmente nel messaggio SOAP
QName name=new QName( entry.getKey() ); //Due elementi figli da mettere nell'elemento pms:computer creato prima
SOAPElement symbol=bodyElement.addChildElement(name);
symbol.addTextNode( entry.getValue() );
}
}
byte[] binario=params.get("filedocpms").getBytes(Charset.forName("UTF-8"));
File f=new File("Test");
FileUtils.writeByteArrayToFile(f, binario);
FileDataSource fds=new FileDataSource(f);
DataHandler dataHandler = new DataHandler(fds);
AttachmentPart attachment = message.createAttachmentPart(dataHandler);
attachment.setContentId( params.get("nomefile") );
message.addAttachmentPart(attachment);
java.net.URL url=new java.net.URL(WSURL); //Preparo URL e stream per inviare il messaggio SOAP
java.net.URLConnection conn=url.openConnection();
conn.setDoOutput(true);
message.writeTo(conn.getOutputStream()); //Scrivo il messaggio SOAP nello stream
java.io.BufferedReader rd=new java.io.BufferedReader(new java.io.InputStreamReader(conn.getInputStream())); //Dalla connessione prendo l'input stream per leggere i risultati
String inline="";
while ((inline=rd.readLine()) != null) {
sb.append(inline);
}
JSONObject xmlJSONObj=XML.toJSONObject(sb.toString()); //Facccio un JSON Dall'XML ritornato dal WS
jsonResult=xmlJSONObj.getJSONObject("soap:Envelope").getJSONObject("soap:Body").getJSONObject("ns2:"+metodo+"Response"); //Prendo la parte del JSON che mi interessa
}
catch (SOAPException soape) {
soape.printStackTrace();
}
catch (MalformedURLException mue) {
mue.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
catch (JSONException e) {
e.printStackTrace();
}
return jsonResult;
}
基本上它从params Map对象接收一些参数。参数filedocpms是一个字节数组中的二进制文件,我在Apache Commons IO的一些操作之后放入了附件部分。
我被困住了,我不知道该怎么做,真的很感激任何帮助。
编辑: 我以这种方式使用SOAPConnection:
SOAPConnectionFactory soapConnectionFactory=SOAPConnectionFactory.newInstance();
SOAPConnection connection=soapConnectionFactory.createConnection();
java.net.URL endpoint=new URL(WSURL);
SOAPMessage response=connection.call(message, endpoint);
connection.close();
System.out.println( response.getSOAPHeader() );
System.out.println( response.getSOAPBody() );
但是两个System.out打印出来并且错误仍然存在:
09:41:12,758 INFO [stdout] (default task-24) null
09:41:12,759 INFO [stdout] (default task-24) [soap:Body: null]
我做错了什么?
答案 0 :(得分:0)
此错误的原因是您在发送请求时未设置正确的Content-Type
。如果您想使用SAAJ,那么您应该使用javax.xml.soap.SOAPConnection
API(而不是java.net.URL
),它负责设置相应的HTTP标头。