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.
Related
With the following code I am able to read the template from my account and send an email with that template is working.
EnvelopesApi envelopesApi1 = createEnvelopesApi(basePath,
prop.getProperty("authenticationToken"));
EnvelopeDefinition envelope1 = makeEnvelope(signerEmail, signerName);
EnvelopeSummary result = envelopesApi1.createEnvelope(accountId, envelope1);
// session.setEnvelopeId(result.getEnvelopeId());
DoneExample.createDefault("Cusotm title")
.withJsonObject(result)
.withMessage("The envelope has been created and sent!<br/>Envelope ID "
+ result.getEnvelopeId() + ".")
.addToModel(model);
But my application is embedded application, so the approval needs to be done over application Hence I have tried to integrate the same in my embedded application.But I am getting error. My code is below.
// Next, create the top level envelope definition and populate it.
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition();
envelopeDefinition.setEmailSubject("Please sign this document!!");
envelopeDefinition.setEmailBlurb("this is the custom mail content");
//envelopeDefinition.setDocuments(Arrays.asList(document));
envelopeDefinition.setTemplateId("6fcd32d8-91f6-4f4f-90f8-8b54eb71bfb8");
envelopeDefinition.setTemplateRoles(Arrays.asList(signer1));
// Add the recipient to the envelope object
Recipients recipients = new Recipients();
//recipients.setSigners(Arrays.asList(signer));
//envelopeDefinition.setRecipients(recipients);
envelopeDefinition.setStatus("sent");
// requests that the envelope be created and sent.
// Step 2. Call DocuSign to create and send the envelope
ApiClient apiClient = new ApiClient(basePath);
apiClient.setAccessToken(accessToken, tokenExpirationSeconds);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
EnvelopeSummary results = envelopesApi.createEnvelope(accountId, envelopeDefinition);
String envelopeId = results.getEnvelopeId();
// Step 3. The envelope has been created.
// Request a Recipient View URL (the Signing Ceremony URL)
RecipientViewRequest viewRequest = new RecipientViewRequest();
// Set the url where you want the recipient to go once they are done signing
// should typically be a callback route somewhere in your app.
viewRequest.setReturnUrl(baseUrl + "/ds-return");
viewRequest.setAuthenticationMethod(authenticationMethod);
viewRequest.setEmail(signerEmail);
viewRequest.setUserName(signerName);
viewRequest.setClientUserId(clientUserId);
// call the CreateRecipientView API
ViewUrl results1 = envelopesApi.createRecipientView(accountId, envelopeId, viewRequest);
// Step 4. The Recipient View URL (the Signing Ceremony URL) has been received.
// The user's browser will be redirected to it.
String redirectUrl = results1.getUrl();
redirect = new RedirectView(redirectUrl);
redirect.setExposeModelAttributes(false);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return redirect;
}
Here I am getting the below error.
com.docusign.esign.client.ApiException:
Error while requesting server, received a non successful
HTTP code 400 with response Body:
'{"errorCode":"UNKNOWN_ENVELOPE_RECIPIENT",
"message":"The recipient you have identified is not a valid
recipient of the specified envelope."}'
at com.docusign.esign.client.ApiClient.invokeAPI(ApiClient.java:1177)
~[docusign-esign-java-3.2.0.jar:na]
at com.docusign.esign.api.EnvelopesApi.createRecipientView(EnvelopesApi.java:1262)
~[docusign-esign-java-3.2.0.jar:na]
....
There are two ways to solve this problem, one is my below alternate way and the second one is as Larry suggested in the comment just add the clientUserId to the signer recipient when you send the envelope.
For embedded sign we need to go for CompositeTemplate
private EnvelopeDefinition makeEnvelope(String signerEmail, String signerName, String clientUserId, WorkArguments args) throws IOException {
CarbonCopy cc1 = new CarbonCopy();
cc1.setEmail("mail");
cc1.setName("name");
cc1.setRoleName(EnvelopeHelpers.CC_ROLE_NAME);
cc1.setRecipientId("2");
// create a composite template for the server template
CompositeTemplate compTemplate1 = new CompositeTemplate();
compTemplate1.setCompositeTemplateId("1");
ServerTemplate serverTemplates = new ServerTemplate();
serverTemplates.setSequence("1");
serverTemplates.setTemplateId("dafgs345-546sdf4-3546sdfqew");
compTemplate1.setServerTemplates(Arrays.asList(serverTemplates));
// Add the roles via an inlineTemplate object
InlineTemplate inlineTemplate = new InlineTemplate();
inlineTemplate.setSequence("1");
inlineTemplate.setRecipients(EnvelopeHelpers.createRecipients(createSigner(signerEmail,signerName,clientUserId), cc1));
compTemplate1.setInlineTemplates(Arrays.asList(inlineTemplate));
// The signer recipient for the added document with a tab definition
Tabs signer1Tabs = EnvelopeHelpers.createSingleSignerTab("**signature_1**", ANCHOR_OFFSET_Y, ANCHOR_OFFSET_X);
signer1Tabs.textTabs(Arrays.asList(
createText("text", "453", "110","Customized data"),
createText("numbersOnly", "453", "130", "147896")));
Signer signer1AddedDoc = createSigner(signerEmail, signerName,clientUserId);
signer1AddedDoc.setAccessCode("12345");
signer1AddedDoc.setTabs(signer1Tabs);
// Create the HTML document
byte[] htmlDoc = EnvelopeHelpers.createHtmlFromTemplateFile(HTML_DOCUMENT_FILE_NAME, "args", args);
// Create a composite template for the added document and add the recipients via an inlineTemplate
CompositeTemplate compTemplate2 = new CompositeTemplate();
compTemplate2.setCompositeTemplateId("2");
InlineTemplate inlineTemplate2 = new InlineTemplate();
inlineTemplate2.setSequence("2");
inlineTemplate2.setRecipients(EnvelopeHelpers.createRecipients(signer1AddedDoc, cc1));
compTemplate2.setInlineTemplates(Arrays.asList(inlineTemplate2));
compTemplate2.setDocument(EnvelopeHelpers.createDocument(htmlDoc, HTML_DOCUMENT_NAME,
DocumentType.HTML.getDefaultFileExtention(), "1"));
EnvelopeDefinition env = new EnvelopeDefinition();
env.setStatus(EnvelopeHelpers.ENVELOPE_STATUS_SENT);
env.setCompositeTemplates(Arrays.asList(compTemplate1, compTemplate2));
return env;
}
and then we can call the api
EnvelopeDefinition envelope = makeEnvelope(signerEmail, signerName, clientUserId, args);
EnvelopeSummary envelopResults = envelopesApi2.createEnvelope(accountId, envelope);
RecipientViewRequest viewRequest1 = makeRecipientViewRequest(args);
ViewUrl viewUrl = envelopesApi2.createRecipientView(accountId, envelopResults.getEnvelopeId(), viewRequest1);
return new RedirectView(viewUrl.getUrl());
Solr/SolrJ Version: 6.0.0
I've set termvector component in solrconfig.xml, and the request handler is "/tvrh", I test it in the browser and this works. Now I want to use it in solrJ, but it only returns the document. The following is my code:
SolrClient solrClient = new HttpSolrClient("http://localhost:8983/solr/test");
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(String.format("id:%s","clueweb12-0000tw-06-17744"));
solrQuery.setRequestHandler("/tvrh");
solrQuery.set("tv", true);
solrQuery.set("tv.all", true);
QueryResponse response = solrClient.query(solrQuery);
SolrDocumentList docs = response.getResults();
for (SolrDocument doc: docs){
for (String key: doc.keySet()){
System.out.println(key);
System.out.println(doc.getFieldValue(key));
}
}
Your question is how to use a non standard request handler in solr.
Be aware that the Term Vector Component belongs to a "non standard" request handler and is not supported from solrj:
https://cwiki.apache.org/confluence/display/solr/The+Term+Vector+Component#TheTermVectorComponent-SolrJandtheTermVectorComponent
You can call "/tvrh" via solrj in a generic mode. You can not use the method SolrClient#query(SolrParams params) for this, because in this case the "request handler" is only send as "qt"-Parameter and will not be part of the url-path (and qt-Parameter is ignored by default).
So please try the method "SolrClient#request" instead.
As #Karsten R says, we could not use SolrClient.query to send request. After I searched a lot and experimented a lot, the following code could work.
SolrClient solrClient = new HttpSolrClient("http://localhost:8983/solr/trecB13");
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(String.format("id:%s","clueweb12-0000tw-06-17744"));
solrQuery.setRequestHandler("/tvrh");
solrQuery.set("tv", true);
solrQuery.set("tv.all", true);
try {
NamedList<Object> response = solrClient.request(new QueryRequest(solrQuery));
TermVectorExtractor extractor = new TermVectorExtractor(response);
System.out.println(extractor.getTermVectorInfo());
} catch (Exception e) {
e.printStackTrace();
}
TermVectorExtractor.java reference Sakai-Solr Github code, the function of the class is to parse resonse object and get term info. A little different from original code. The different has been shown below.
import org.apache.solr.common.util.NamedList;
import java.util.*;
public class TermVectorExtractor {
private static final String TERM_VECTORS = "termVectors";
private Map<String, Map<String, Map<String, TermInfo>>> termVectorInfo = Collections.emptyMap();
/**
* Creates a TermVectorExtractor for the given query response sent by Solr.
*
* #param queryResponse response sent by the solr server for a search query.
*/
#SuppressWarnings("unchecked")
public TermVectorExtractor(NamedList<Object> queryResponse) {
NamedList<Object> res = (NamedList<Object>) queryResponse.get(TERM_VECTORS);
if (res != null)
termVectorInfo = extractTermVectorInfo(res);
}
}
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.
When I use the following method :
public String getProjectList() {
projNames = new ArrayList<>();
projNames.add("Project1");
projNames.add("Project2");
projNames.add("Project3");
return new Gson().toJson(projNames);
in the following code :
$(document).ready(function() {
$.getJSON('DBDropDown', function(resp) { // on sucess
var $select = $('#someselect');
$select.find('option').remove();
$select.prepend("<option value='Select Project'></option>").val('');
$.each(resp, function(key, value) { // Iterate over the JSON object.
$('<option>').val(key).text(value).appendTo($select); // Create HTML <option> element, set its value with currently iterated key and its text content with currently iterated item and finally append it to the <select>.
});
}).fail(function() { // on failure
alert("Request failed.");
});
});
and my JSP call is :
response.getWriter().write(MusicDatabase
.getInstance()
.getProjectList()
I am able to get the dropdown menu. But when I use this method in place of getProjectList I dont get a response when I check chrome developer tools and debug.
public String Names() throws URISyntaxException{
names = new ArrayList<>();
URI uri = new URI("https://jira.xxxxx.com");
JiraRestClientFactory jrcf = new AsynchronousJiraRestClientFactory();
JiraRestClient jrc = jrcf.createWithBasicHttpAuthentication(uri, "xxx", "xxxx");
Iterable<BasicProject> allproject = jrc.getProjectClient().getAllProjects().claim();
for(BasicProject project : allproject){
names.add(project.getName());
}
return new Gson().toJson(names);
}
I am not getting any response and console throws ClassDefNotFound Exception when I already have all the classes needed. Help me if you have gone through this type of issue.
Thanks
I need to call this service in Java -
https://api.semantics3.com/test/v1/products?q={"cat_id": "13658", "brand": "Toshiba", "model": "Satellite"}
I've managed to do this in python as follows -
class Semantics:
def __init__(self):
self.service_address = 'https://api.semantics3.com/test/v1/products?'
self.api_key = 'SEM3158A71D4AB3A3715C2230B96943F46D0'
def query(self, params):
query = 'q=' + params.__dict__.__str__().replace("'",'"')
query = urlencode(urlparse.parse_qs(query), True)
req = Request(url = self.service_address + query)
req.add_header('api_key', self.api_key)
return urlopen(req).read()
class QueryParams:
def __init__(self, cat_id, model, brand):
self.cat_id = cat_id
self.model = model
self.brand = brand
qp = QueryParams('13658', 'Satellite', "Toshiba")
print Semantics().query(qp)
I have tried writing an equivalent Java program using Spring REST API and Apache HttpClient to no avail. I can't find a way to set a dictionary (i.e. Map) into the query String.
public static void main(String[] args) {
String uri = "https://api.semantics3.com/test/v1/products?";
HttpClient hc = new HttpClient();
GetMethod method = new GetMethod(uri);
method.getParams().setParameter("q", "Toshiba");//How do I insert a Map here?
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
method.setRequestHeader("api_key", "SEM2158A71D4AB3A3715C2435B96943F46D0");
try {
int statusCode = hc.executeMethod(method);
System.out.println(statusCode);
byte[] responseBody = method.getResponseBody();
System.out.println(new String(responseBody));
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
method.releaseConnection();
}
}
At the lowest level I can manually produce the query string manually via concatenation and then Url encode it. But is there a more elegant way to do it?
I think you can use external jar like GSON to convert the Map into JSON
Map<String, String> map = new HashMap<String,String>();
map.put("cat_id", "12345");
..
Gson gson = new Gson();
method.getParams().setParameter("q", gson.toJson(map));
Have a look at Google's Http Client
As you can see from the examples, it uses objects to build the request url and deserialise the response body. The docs also show you how to deserialise JSON specifically, and you can choose your JSON library of choice.