I'm calling a service in which I'm setting the OUTBOUND_MESSAGE_ATTACHMENTS in the following way:
Map<String, DataHandler> attachmentsMap = (Map<String, DataHandler>) context.get(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS);
ByteArrayDataSource bads = new ByteArrayDataSource(file, PDF_MIME_TYPE);
DataHandler dh = new DataHandler(bads);
AttachmentPart attachmentPart = message.createAttachmentPart();
attachmentPart.setContent(new ByteArrayInputStream(file), PDF_MIME_TYPE);
attachmentPart.setContentId(fileId);
String contentDisposition = "Content-Disposition: attachment; name=\"" + fileId + "\"";
attachmentPart.addMimeHeader("Content-Disposition", contentDisposition);
message.addAttachmentPart(attachmentPart);
attachmentsMap.put(fileId, dh);
And on server side I expect to find the same information in the INBOUND_MESSAGE_ATTACHMENTS but seems that nothing is sent.
Can you please what I'm doing wrong?
After all I found the solution by myself.
I had to you CXF implementation from Apache and I have to enable the property for writing the attachment.
JaxWsClientFactoryBean clientFactoryBean = new JaxWsClientFactoryBean();
clientFactoryBean.setServiceClass(DocumentManagementForUnderwritingService.class);
clientFactoryBean.setAddress(serviceURL);
JaxWsProxyFactoryBean pfb = new JaxWsProxyFactoryBean(clientFactoryBean);
DocumentUploadHandler.enableSoapClientOutputAttachments(pfb);
DocumentManagementForUnderwritingService proxyy = (DocumentManagementForUnderwritingService) pfb.create();
Below I set the property:
DocumentUploadHandler.enableSoapClientOutputAttachments(pfb);
And the method from the handler is:
public static void enableSoapClientOutputAttachments(JaxWsProxyFactoryBean pfb){
Map<String,Object> props = new HashMap<String, Object>();
props.put(AttachmentOutInterceptor.WRITE_ATTACHMENTS, Boolean.TRUE);
pfb.setProperties(props);
pfb.getOutInterceptors().add(new SwAOutInterceptor());
pfb.getOutInterceptors().add(new AttachmentOutInterceptor());
}
After I created the proxy, I chained the handler:
Binding binding = proxy.getBinding();
#SuppressWarnings("rawtypes")
final List<Handler> handlerChain = binding.getHandlerChain();
handlerChain.add(documentUploadHandler);
binding.setHandlerChain(handlerChain );
And the code from the handler is present in the question.
Hope this will help someone else in the future.
Related
Am trying to call third party web service using java apache CXF. I created the proxy using CXF apache plugin. The service is protected using X509 Authentication, Signature and Encryption.
When I call the service, am getting the below exception.
Apache CXF Policy Exception Reference to policy "X509 Authentication, Signature and Encryption" could not be resolved
This is what I tried sofar..
ServiceEnq service=new ServiceEnq(new
URL("https://.....Inquiry?wsdl"));
System.out.println("Line2 scuccess!");
InquiryPortType port=service.getInquiryPort();
Client client = ClientProxy.getClient(port);
org.apache.cxf.endpoint.Endpoint endpoint = client.getEndpoint();
HashMap<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION,
"UsernameToken Timestamp Signature Encryption");
outProps.put(WSHandlerConstants.USER, "username1");
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class.getName());
outProps.put(WSHandlerConstants.ENCRYPTION_USER, "public1");
outProps.put(WSHandlerConstants.ENC_PROP_FILE, "publicProp.properties");
outProps.put(WSHandlerConstants.SIGNATURE_USER, "pk");
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "pkProp.properties");
outProps.put("timeToLive", "30");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
endpoint.getOutInterceptors().add(wssOut);
HashMap<String, Object> inProps = new HashMap<>();
inProps.put(WSHandlerConstants.ACTION, "Encryption Signature Timestamp");
inProps.put(WSHandlerConstants.DEC_PROP_FILE, "publicProp.properties");
inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class.getName());
inProps.put(WSHandlerConstants.SIG_PROP_FILE, "pkProp.properties");
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
endpoint.getInInterceptors().add(wssIn);
ObjectFactory fact=new ObjectFactory();
InquiryRequest request=fact.createInquiryRequest();
MessageHeaderIn headerIn=fact.createMessageHeaderIn();
// removed input parameters
// getting error in this line...
InquiryResponse2 res= port.Inquiry(request);
I have manually created the XML Document and used wss4j to encrypt and sign XML document. Then uploaded the generated SOAP envelope to HttpURLConnection using POST method.
Here is the java code to sign and encryption. I have avoided other code as this is more tricky part..
public void addSignature(org.w3c.dom.Document doc) {
try {
Properties properties = new Properties();
properties.put("org.apache.ws.security.crypto.merlin.keystore.password", SecurityConstants.JKSPassword);
properties.put("org.apache.ws.security.crypto.merlin.keystore.file",
SecurityConstants.ClientCert);
properties.put("org.apache.ws.security.crypto.merlin.keystore.alias",
SecurityConstants.ClientKeyAliasName);
Merlin keyMaterialCrypto = new Merlin(properties);
WSSecSignature wssSign = new WSSecSignature();
wssSign.setUserInfo(SecurityConstants.ClientKeyAliasName, SecurityConstants.JKSPassword);
wssSign.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
wssSign.setUseSingleCertificate(false);
org.apache.ws.security.message.WSSecHeader secHeader = new WSSecHeader();
secHeader.setMustUnderstand(false);
secHeader.insertSecurityHeader(doc);
wssSign.build(doc, keyMaterialCrypto, secHeader);
} catch (Exception e) {
e.printStackTrace();
System.out.print(e.toString());
}
}
public void addEnccryption(Document doc) {
StringWriter writer = null;
try {
Properties properties = new Properties();
properties.put("org.apache.ws.security.crypto.merlin.keystore.password", SecurityConstants.JKSPassword);
properties.put("org.apache.ws.security.crypto.merlin.keystore.file",
SecurityConstants.ServerCer);
properties.put("org.apache.ws.security.crypto.merlin.keystore.alias",
SecurityConstants.ServerAliasName);
Merlin crypto = new Merlin(properties);
WSSecEncrypt wsEncryption = new WSSecEncrypt();
WSSConfig wssConfig = WSSConfig.getNewInstance();
wsEncryption.setWsConfig(wssConfig);
wsEncryption.setUserInfo(SecurityConstants.ServerAliasName);
wsEncryption.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
wsEncryption.setEncryptSymmKey(true);
org.apache.ws.security.message.WSSecHeader secHeader = new WSSecHeader();
secHeader.setMustUnderstand(false);
secHeader.insertSecurityHeader(doc);
wsEncryption.build(doc, crypto, secHeader);
} catch (Exception e) {
e.printStackTrace();
}
}
I am trying to call the Ejabberd command create_room_with_opts via XMLRPC using the apache XMLRPC api. The following is the code I am using.
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL(<EJABBERD_HOST_URL>));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
// Command string
String command = "create_room_with_opts";
Map<String, Object> struct1 = new HashMap<String, Object>();
struct1.put("user", <ADMIN_USERNAME>);
struct1.put("server", <HOST>);
struct1.put("password", <ADMIN_PASSWORD>);
struct1.put("admin", Boolean.TRUE);
Map<String, Object> struct = new HashMap<String, Object>();
struct.put("name", "testroom");
struct.put("service", <NAME_OF_SERVICE>);
struct.put("host", <HOST>);
struct.put("options", getOpts());
HashMap result = (HashMap) client.execute(command, params);
static Object[] getOpts() {
Object opt[] = new Object[1];
HashMap<String, Object> option = new HashMap<String, Object>();
HashMap<String, Object> optionTuple = new HashMap<String, Object>();
option.put("name", "public");
option.put("value", Boolean.TRUE);
optionTuple.put("option", option);
return opt;
}
However, when I run this code I get the following exception.
org.apache.xmlrpc.XmlRpcException: Error -122
Parameter '{struct,[{name,<<"public">>},{value,<<"true">>}]}' can't be coerced to type '{tuple,[{name,binary},{value,binary}]}'
at org.apache.xmlrpc.client.XmlRpcStreamTransport.readResponse(XmlRpcStreamTransport.java:181)
at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:149)
at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:95)
at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.sendRequest(XmlRpcSunHttpTransport.java:39)
at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:53)
at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:166)
at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:136)
at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:125)
I am unable to identify the problem in this code.
I have tried the example given in the ejabberd documentation at the API-Documentation,
but it seems that there is a syntax error in that example.
I am able to call the other commands(for example create_room, register, etc) for the same Ejabberd server successfully, so I know that the configuration is correct.
I am using JDK1.7 and apache XMLRPC api 3.1.3
Is there any other example(for create_room_with_opts command) which I can check.
It's not clear from the google-http-java-client* docs how you would go about posting a form that has a file field.
For example I'm trying to print a document using the Google Cloud Print API:
HttpRequestFactory httpRequestFactory = getHttpRequestFactory();
Map<String, Object> parameters = Maps.newHashMap();
parameters.put("printerId", printRequest.getPrinterId());
parameters.put("title", printRequest.getTitle());
parameters.put("contentType", printRequest.getContentType());
parameters.put("ticket", new Gson().toJson(printRequest.getOptions()));
MultipartContent content = new MultipartContent();
content.addPart(new MultipartContent.Part(new UrlEncodedContent(parameters)));
content.addPart(new MultipartContent.Part(
new FileContent(printRequest.getContentType(), printRequest.getFile())));
try {
HttpResponse response = httpRequestFactory.buildPostRequest(
SubmitUrl, content).execute();
System.out.println(IOUtils.toString(response.getContent()));
} catch (IOException e) {
String message = String.format();
System.out.println("Error submitting print job: " + e.getMessage());
}
Unfortunately this doesn't work. The API returns the error "Printer Id required for this request." which seems to me like the request isn't properly formed.
What am I doing wrong?
* I'm specifically using the google-http-java-client as it handles automatic refreshing of OAuth tokens etc for me. Please don't reply with solutions that involve using other HTTP clients.
So it looks like I misunderstood how form fields are added to multipart messages. The working code now looks like this
HttpRequestFactory httpRequestFactory = getHttpRequestFactory(username);
Map<String, String> parameters = Maps.newHashMap();
parameters.put("printerid", printRequest.getPrinterId());
parameters.put("title", printRequest.getTitle());
parameters.put("contentType", printRequest.getContentType());
// Map print options into CJT structure
Map<String, Object> options = Maps.newHashMap();
options.put("version", "1.0");
options.put("print", printRequest.getOptions());
parameters.put("ticket", new Gson().toJson(options));
// Add parameters
MultipartContent content = new MultipartContent().setMediaType(
new HttpMediaType("multipart/form-data")
.setParameter("boundary", "__END_OF_PART__"));
for (String name : parameters.keySet()) {
MultipartContent.Part part = new MultipartContent.Part(
new ByteArrayContent(null, parameters.get(name).getBytes()));
part.setHeaders(new HttpHeaders().set(
"Content-Disposition", String.format("form-data; name=\"%s\"", name)));
content.addPart(part);
}
// Add file
FileContent fileContent = new FileContent(
printRequest.getContentType(), printRequest.getFile());
MultipartContent.Part part = new MultipartContent.Part(fileContent);
part.setHeaders(new HttpHeaders().set(
"Content-Disposition",
String.format("form-data; name=\"content\"; filename=\"%s\"", printRequest.getFile().getName())));
content.addPart(part);
try {
HttpResponse response = httpRequestFactory.buildPostRequest(
SubmitUrl, content).execute();
System.out.println(IOUtils.toString(response.getContent()));
} catch (IOException e) {
...
}
The most important parts above were overriding the default HttpMediaType to specify "multipart/form-data" and adding each field as its own part with a "Content-Disposition" header to designate the form field name.
The paging function, and a local filtering is perfect, but i need the REMOTE filter, and i wanna sending the filters parameter to the request method.
Thx!
I have this code:
String path = GWT.getHostPageBaseURL() + (Examples.isExplorer() ? "" : "../../" ) + "backend/index.php?action=getLines";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
HttpProxy<String> proxy = new HttpProxy<String>(builder);
JsonPagingLoadResultReader<PagingLoadResult<ModelData>> reader = new JsonPagingLoadResultReader<PagingLoadResult<ModelData>>(type);
final PagingLoader<PagingLoadResult<ModelData>> loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy,
reader);
[...]
NumericFilter sorszamFilter = new NumericFilter("Sorszam");
StringFilter nevFilter = new StringFilter("Nev");
DateFilter datumFilter = new DateFilter("Datum");
NumericFilter szamFilter = new NumericFilter("Szam");
GridFilters filters = new GridFilters();
filters.setLocal(true);
filters.addFilter(sorszamFilter);
filters.addFilter(nevFilter);
filters.addFilter(datumFilter);
filters.addFilter(szamFilter);
//example
sorszamFilter.addListener(Events.Update, new Listener<FilterEvent>() {
#Override
public void handleEvent(FilterEvent be) {
???
}
});
[...]
final PagingToolBar toolBar = new PagingToolBar(10);
toolBar.bind(loader);
loader.load(0, 10);
It looks like the BasePagingLoader can get be customized using a loadConfig object. The loadConfig should be an Object of a ModelData type and more specifically a PagingLoadConfig.
Create a new loadConfig using the
final ModelData loadConfig = (ModelData) ((BasePagingLoader).loader).newLoadConfig();
method.
Then force the loader to use this loadConfig:
((BasePagingLoader).loader).useLoadConfig(loadConfig);
loadConfig should be a mutable instance of a ModelData. That is why you can add new properties to it using the
loadConfig.set("selectedFilter", "what_ever_you_like_here")
loadConfig.set("direction", "ASC");
This should be done in place of the question marks you put and should force the HttpProxy to add whatever you set to the loadConfig properties. (see the HttpProxy#generateUrl method for reference on how the request is build with an aid of a loadConfig). Then you'll have to process the request correspondingly on server-side.
I'm assuming you use GXT 2.2.x, and honestly I haven't compiled it, hope it works fine.
New to SharePoint.
I'm trying to upload a document to SharePoint using it's CopyIntoItems web service method with Java but keep on getting 400 Bad Request. I've use the Java's wsimport to generate the class files from the .wsdl file. Here is my Java code with the generated classes.
public static void createDocument(CopySoap port) {
String url = SoapPortProvider.spSiteUrl + "/Shared Documents/Temp Folder/test.txt";
String sourceUrl = "http://null";
byte[] content = IoUtil.getBytes(new File("C:/CopyFile/READ-ME.txt"));
FieldInformation descInfo = new FieldInformation ();
descInfo.setDisplayName("Test Doc");
descInfo.setType(FieldType.TEXT);
descInfo.setValue("Test uploaded file");
DestinationUrlCollection urls = new DestinationUrlCollection();
urls.getString().add(url);
FieldInformationCollection infos = new FieldInformationCollection ();
infos.getFieldInformation().add(descInfo);
CopyResultCollection results = new CopyResultCollection ();
Holder<CopyResultCollection> resultHolder = new Holder<CopyResultCollection>(results);
Holder<Long> longHolder = new Holder<Long>(new Long(-1));
port.copyIntoItems(sourceUrl, urls, infos, content, longHolder, resultHolder);
}
My SOAP Request looks like
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<CopyIntoItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<SourceUrl>http://null</SourceUrl>
<DestinationUrls>
<string>https://www.mysite.com/sites/TestSite/Shared Documents/Temp Folder/test.txt</string>
</DestinationUrls>
<Fields>
<FieldInformation Value="Test uploaded file" DisplayName="Test Doc" Type="Text"/>
</Fields>
<Stream>KioqTWFrZSBzdXJlIHRoZSBjb250ZW50IGlzIHVuZGVyIEM6L0NvcHlGaWxlLy4gICoqKg0KDQpUbyBydW46DQoNCjEuICBFZGl0IHRoZSBkZXBsb3kucHJvcHMgZmlsZS4gIFNwZWNpZnkgdGhlIHNvdXJjZSAoZm9sZGVyIHRoYXQgY29udGFpbiBpdGVtcyB0byBkZXBsb3kpLCBkZXN0aW5hdGlvbiAoZm9sZGVyIHRvIGRlcGxveSB0byksIGFuZCBmaWxlcyAodGhlIGl0ZW1zIHRvIGRlcGxveSkuDQoyLiAgRG91YmxlIGNsaWNrIG9uIGRlcGxveUN1c3RvbWl6YXRpb24uYmF0DQoNCk5vdGUgdGhhdCBhIGxvZyBvZiB0aGUgcHJvZ3Jlc3Mgd2lsbCBiZSBjcmVhdGVkIGluIEM6L0NvcHlGaWxlL2NvcHlGaWxlLmxvZyANCg0KTm90ZSB0aGF0LCBmb3IgcHJlY2F1dGlvbiwgZXhpc3RpbmcgZmlsZSB3aWxsIG5vdCBiZSBvdmVyd3JpdHRlbiwgaW5zdGVhZCB3aWxsIGJlIHNhdmVkIGFzIHlvdXJfY29kZV9maWxlLm9sZA==</Stream>
</CopyIntoItems>
</S:Body>
</S:Envelope>
And the response I get is
null: HTTP/1.1 400 Bad Request
Content-length: 0
X-powered-by: ASP.NET
Server: Microsoft-IIS/7.5
Date: Tue, 14 Feb 2012 16:29:51 GMT
Microsoftsharepointteamservices: 14.0.0.5138
which doesn't tell me much. What could be missing?
I have use the Following code its work perfectly for me:
try {
//Copy WebService Settings
string webUrl = "http://sharepointportal.ABC.com/";
WSCopy.Copy copyService = new WSCopy.Copy();
copyService.Url = webUrl + "/_vti_bin/copy.asmx";
copyService.Credentials = new NetworkCredential("username", "****", "Domain");
//Declare and initiates the Copy WebService members for uploading
string sourceUrl = "C:\\Work\\Ticket.Doc";
//Change file name if not exist then create new one
string[] destinationUrl = { "http://sharepointportal.ABC.com/personal/username/Document Upload/Testing Document/newUpload.Doc" };
WSCopy.CopyResult cResult1 = new WSCopy.CopyResult();
WSCopy.CopyResult cResult2 = new WSCopy.CopyResult();
WSCopy.CopyResult[] cResultArray = { cResult1, cResult2 };
WSCopy.FieldInformation fFiledInfo = new WSCopy.FieldInformation();
fFiledInfo.DisplayName = "Description";
fFiledInfo.Type = WSCopy.FieldType.Text;
fFiledInfo.Value = "Ticket";
WSCopy.FieldInformation[] fFiledInfoArray = { fFiledInfo };
FileStream strm = new FileStream(sourceUrl, FileMode.Open, FileAccess.Read);
byte[] fileContents = new Byte[strm.Length];
byte[] r = new Byte[strm.Length];
int ia = strm.Read(fileContents, 0, Convert.ToInt32(strm.Length));
strm.Close();
//Copy the document from Local to SharePoint
uint copyresult = copyService.CopyIntoItems(sourceUrl, destinationUrl, fFiledInfoArray, fileContents, out cResultArray);
MessageBox.Show("Suceess");
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
Got it! There is just a bug in my code in initialization. Here is the working code to anyone out there looking to work with SharePoint and Java. I've use JAX-WS wsimport tool to generate the class file from the .wsdl file. You can point the tool straight to the url of the WSDL, for example, https://my.site.come/sites/mysite/_vti_bin/copy.asmx?wsdl
public static CopySoap getPort(String username, String password) {
Copy service = new Copy();
CopySoap port = service.getCopySoap();
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"https://my.site.com/sites/mysite/_vti_bin/copy.asmx");
return port;
}
public static void createDocument(CopySoap port) {
String url = "https://my.site.com/sites/mysite/Shared Documents/Temp Folder/test.txt";
String sourceUrl = "C:\\CopyFile\\READ-ME.txt";
DestinationUrlCollection urls = new DestinationUrlCollection();
urls.getString().add(url);
byte[] content = IoUtil.getBytes(new File(sourceUrl));
FieldInformation titleInfo = new FieldInformation ();
titleInfo.setDisplayName("Title");
titleInfo.setType(FieldType.TEXT);
titleInfo.setValue("Test Doc");
FieldInformationCollection infos = new FieldInformationCollection ();
infos.getFieldInformation().add(titleInfo);
CopyResultCollection results = new CopyResultCollection ();
Holder<CopyResultCollection> resultHolder = new Holder<CopyResultCollection>(results);
Holder<Long> longHolder = new Holder<Long>(new Long(-1));
port.copyIntoItems(sourceUrl, urls, infos, content, longHolder, resultHolder);
}