I have a simple file upload web service as a small part of my project.
This is what I have done so far on the server side :
#POST
#Path("/file")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(List<Attachment> attachments,#Context HttpServletRequest request) {
System.out.println("Got an attachment!");
for(Attachment attr : attachments) {
DataHandler handler = attr.getDataHandler();
try {
InputStream stream = handler.getInputStream();
MultivaluedMap map = attr.getHeaders();
OutputStream out = new FileOutputStream(new File("/home/yashdosi/s/" + getFileName(map))); //getFileName is a seperate private function..
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
stream.close();
out.flush();
out.close();
} catch(Exception e) {
e.printStackTrace();
}
}
return Response.ok("file uploaded").build();
}
It works perfectly well when requests come from html forms...when I try to send a request from a java client it simply doesnt work..!!
Any ideas about on creating a java client for this code..
Here is the code I tried with...maybe there is a simple error in this code but..I dont see it...also as I said this code simple wont work...no errors or anything else....when I tried printing something on the server console to see if the service is invoked...it did NOT print anything..so I think I am unable to contact the service for some reason...
public static void uploadPhoto()
{
String url = "http://localhost:8080/fileupload-ws/services/postdata";
String output = null;
PostMethod mPost = new PostMethod(url);
HttpClient client = new HttpClient();
try
{
File imageFile = new File("/home/yashdosi/1.jpg");
BufferedImage image = ImageIO.read(imageFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
byte[] encodedImage = Base64.encodeBase64(baos.toByteArray());
String data = " " + " " + "" + "image/jpeg" + " " + "" + new String(encodedImage) + " " + "";
mPost.setRequestBody(data);
mPost.setRequestHeader("Content-Type", "text/xml");
client.executeMethod( mPost );
output = mPost.getResponseBodyAsString( );
mPost.releaseConnection( );
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(output);
}
Finally got a client working!!
HttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost("http://localhost:8080/fileupload-ws/services/postdata");
FileBody img = new FileBody(new File("/home/yashdosi/1.jpg"));
FileBody html = new FileBody(new File("/home/yashdosi/hotmail.html"));
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("image", img);
reqEntity.addPart("html", html);
httppost.setEntity(reqEntity);
httppost.setHeader("Content-Type", "multipart/form-data");
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
}
catch(Exception e)
{
e.printStackTrace();
}
finally {
try { httpclient.getConnectionManager().shutdown(); } catch (Exception ignore) {}
}
Related
We are trying to upload a file of size 46GB to AWS S3. However the file upload hangs once it reaches 99%. We are using AWS java SDK for the mulitpart upload.
Following is the code which is used for multipart upload:
void startMultipartUpload(ObjectStoreAccess creds, List<Path> files) {
List<File> filenames = files.stream().map(Path::toString).map(File::new).collect(Collectors.toList());
TransferManager transferManager = transferManagerFactory.createTransferManager(creds);
List<File> filesNotUploaded = new ArrayList<>();
boolean isFileUploadSuccessful;
Integer timeElapsed;
for (File file : filenames) {
isFileUploadSuccessful = false;
timeElapsed = 0;
try {
String keyName = creds.getAwsS3TemporaryUploadCredentials().getKeyPrefix() + file.getName();
PutObjectRequest request = new PutObjectRequest(creds.getAwsS3TemporaryUploadCredentials().getBucketName(), keyName, new File(file.getPath()));
Upload upload = transferManager.upload(request);
logger.info(String.format("Starting upload for : %s ", file.getName()));
while (!upload.getState().equals(Transfer.TransferState.Completed)) {
Thread.sleep(1000);
timeElapsed++;
progressLogger.writeProgress(timeElapsed, upload.getProgress().getPercentTransferred());
}
upload.waitForCompletion();
isFileUploadSuccessful = true;
progressLogger.writeProgressStatus("...upload complete!\n");
} catch (AmazonServiceException e) {
String message = "AmazonServiceException: " + e.getMessage();
logger.error(message);
} catch (SdkClientException e) {
String message = "SdkClientException: " + e.getMessage();
logger.error(message);
} catch (InterruptedException e) {
String message = "InterruptedException: " + e.getMessage();
logger.error(message);
Thread.currentThread().interrupt();
} finally {
if (!isFileUploadSuccessful) {
String message = this.appMessages.getMessageByKey("FAIL_TO_UPLOAD_FILE") + " " + file.getPath();
logger.error(message);
filesNotUploaded.add(file);
}
}
}
}
Try using the AWS SDK for Java V2 and following this example that shows how to upload an object in parts. See:
https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java
I am currently working on a Spring WebFlux project that connects to ElasticSearch. I have a Rest Service that in turn calls a method in the Service Layer that connects to the ES. I am having trouble writing UnitTests for my Service Layer. Any help would be appreciated as this is the first time I am working with Reactive Programming. Below are the code snippets for my Controller and Service methods.
Controller Code :
#GetMapping(path = "/api/apis/services/{id}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Flux<ClassA> serviceApis(#PathVariable final String serviceKey) {
return apiService.getDataForService(serviceKey);
}
Service Layer :
#PreAuthorize("isFullyAuthenticated()")
public Flux<ClassA> getDataForService(
final String id) {
IdentityToken token = GSLSecurityContext.getCurrentUserIdentityToken();
if (token == null) {
return Flux.error(new Exception("No token found"));
}
String securityQueryJson = getSecurityShould(token);
String queryToRun = QUERY
.replace("XXX_SIZE_XXX", config.getValueAsString("scroll.size"))
.replace("XXX_SECURITY_SHOULD_XXX", securityQueryJson)
.replace("XXX_SERVICE_KEY_XXX", id);
WebClient client = ClientUtil.getDataLakeWebClient(config);
Flux<ClassA> response = getData(client, queryToRun);
return response;
}
The getData code is as below :
protected Flux<ClassA> getData(
final WebClient client,
final String queryToRun) {
String scrollTimeoutQuery = "?scroll=" + config.getValueAsString("scroll.timeout");
long timeout = config.getValueAsLong("query.timout");
return Flux.generate(
() -> null,
(scrollId, sink) -> {
ClassAWrapper lastWrapper = null;
if (scrollId == null) {
Mono<ClassAWrapper> wrapper = client.post()
.uri(getSearchURI() + scrollTimeoutQuery)
.body(BodyInserters.fromObject(queryToRun)).retrieve()
.bodyToMono(ClassAWrapper.class)
.onErrorMap(original -> new Exception("Unable to retrieve from elastic search for query " + queryToRun, original))
.log();
try {
lastWrapper = wrapper.block(Duration.ofSeconds(timeout));
} catch (IllegalStateException ex) {
LOG.error("Timedout after " + timeout + " seconds while getting data from elastic search for query " + queryToRun);
lastWrapper = null;
} catch (Exception ex) {
LOG.error("Error in getting message details",ex);
lastWrapper = null;
}
} else {
String scrollQuery = "{\"scroll\" : \"" + config.getValueAsString("scroll.timeout") + "\", \"scroll_id\" : \"" + scrollId + "\"}";
Mono<ClassAWrapper> wrapper = client.post()
.uri("_search/scroll")
.body(BodyInserters.fromObject(scrollQuery)).retrieve()
.bodyToMono(ClassAWrapper.class)
.onErrorMap(original -> new Exception("Unable to retrieve next page of data from elastic search", original))
.log();
try {
lastWrapper = wrapper.block(Duration.ofSeconds(timeout));
} catch (IllegalStateException ex) {
LOG.error("Timeout after " + timeout + " seconds while getting data from elastic search for query " + queryToRun);
lastWrapper = null;
} catch (Exception ex) {
LOG.error("Error in getting message details",ex);
lastWrapper = null;
}
}
if (lastWrapper == null || lastWrapper.getResult() == null || lastWrapper.getResult().getDetails().isEmpty()) {
sink.next(new ClassA());
sink.complete();
return null;
}
sink.next(lastWrapper.getResult());
return lastWrapper.getScrollId();
}
);
}
Here, queryToRun is the ES query to be executed. config is the configuration. I need to test the method "getDataForService()".
I am trying to send an XML soap request to a dynamics nav web service. This is the XML from the WSDL. I have created a web access key and its the one in the key parameter of the XML.
<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
<s11:Body>
<ns1:Create xmlns:ns1='urn:microsoft-dynamics-schemas/page/customerws'>
<ns1:CustomerWS>
<ns1:Key>+gn8Nu4i7iW7D/g9vCaI8HZE5IEi1NBkTBqDp5QfXe4=</ns1:Key>
<ns1:Shipping_Advice></ns1:Shipping_Advice>
<ns1:Shipment_Method_Code></ns1:Shipment_Method_Code>
<ns1:Shipping_Agent_Code></ns1:Shipping_Agent_Code>
<ns1:Shipping_Agent_Service_Code></ns1:Shipping_Agent_Service_Code>
<ns1:Shipping_Time></ns1:Shipping_Time>
<ns1:Base_Calendar_Code></ns1:Base_Calendar_Code>
<ns1:Customized_Calendar></ns1:Customized_Calendar>
<ns1:Currency_Code></ns1:Currency_Code>
<ns1:Language_Code></ns1:Language_Code>
<ns1:VAT_Registration_No></ns1:VAT_Registration_No>
</ns1:CustomerWS>
</ns1:Create>
</s11:Body>
</s11:Envelope>
And this is the code that am using to send this request:
Console.WriteLine("We have started");
string pageName = "http://hrp-dmu.uganda.hrpsolutions.co.ug:9047/DynamicsNAV80/WS/Uganda%20Management%20Institute/Page/CustomerWS";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(pageName);
req.Method = "POST";
req.ContentType = "text/xml;charset=UTF-8";
req.ProtocolVersion = new Version(1, 1);
req.Headers.Add("SOAPAction", #"urn:microsoftdynamicsschemas/page/customerws:Create");
Console.WriteLine("After preparing request object");
string xmlRequest = GetTextFromXMLFile("E:\\tst3.xml");
Console.WriteLine("xml request : "+xmlRequest);
byte[] reqBytes = new UTF8Encoding().GetBytes(xmlRequest);
req.ContentLength = reqBytes.Length;
try
{
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(reqBytes, 0, reqBytes.Length);
}
}
catch (Exception ex)
{
Console.WriteLine("GetRequestStreamException : " + ex.Message);
}
HttpWebResponse resp = null;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (Exception exc)
{
Console.WriteLine("GetResponseException : " + exc.Message);
}
string xmlResponse = null;
if (resp == null)
{
Console.WriteLine("Null response");
}
else
{
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
xmlResponse = sr.ReadToEnd();
}
Console.WriteLine("The response");
Console.WriteLine(xmlResponse);
}
Console.ReadKey();
when using NavUserPassword Authentication you'll need a certificate.
See here on MSDN
Cheers!
I made small application. I made login application. I want call restful web services from action class. I used struts2 framework. I can't change restful web services. Please give me suggestion.
It is solution of my question.
try {
URL url = new URL("http://localhost:8080/ProWebservices/webresources/users/" + emailid + "&" + password + "&photographer");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
JsonObject json = (JsonObject) new JsonParser().parse(output);
String out = (String) json.get("userid").toString();
if(!out.equals("null")){
return "SUCCESS";
}
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I am trying to hit a url(login screen), get the jsessionid(J2EEJSESSIONID) and add it in the cookie store and in turn in to the context and hit the same url with credentials. I am expecting a login successful screen.
However i am bounced with the login screen again.
And, i printed the response header for both the hits. I am expecting both the response with the same J2EESESSIONID to maintain the session. Instead both the session ids are different. Pls help.
Pls find the code below:
HttpEntity entity = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
try{
// Initialization
HttpPost httpPost = new HttpPost("https://yyyyy.xxx.com/enl");
HttpClientExample httpClientExample = new HttpClientExample();
CookieStore cookieStore = new BasicCookieStore();
HttpContext httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet httpGet = new HttpGet("https://yyyyy.xxx.com/enl");
// Execute Get
HttpResponse httpResponse = httpClient.execute(httpGet, httpContext);
// Print the header for 1st url
org.apache.http.Header[] headers = httpResponse.getAllHeaders();
System.out.println("##### Header length::"+headers.length);
for(int i=0;i<headers.length; i++)
{
System.out.println("Header Name::"+headers[i].getName());
System.out.println("Header Val::"+headers[i].getValue());
}
// update Cookie for the next hit
org.apache.http.Header[] cookieHeaders = httpResponse.getHeaders("Set-Cookie");
String html = EntityUtils.toString(httpResponse.getEntity());
cookieStore = httpClientExample.updateCookieStore(cookieHeaders, cookieStore);
httpClient.setCookieStore(cookieStore);
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
// Setting the redirects since i received 302 error
httpClient.setRedirectStrategy(new DefaultRedirectStrategy() {
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
boolean isRedirect=false;
try {
isRedirect = super.isRedirected(request, response, context);
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return false;
}
});
// Added because i received Circular redirect error
httpClient.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
// Execute Post with credentials
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("http://yyyyy.xxx.com", 443),
new UsernamePasswordCredentials("usr", "pswd"));
httpPost.setHeader("Cookie", "JSESSIONID="+ getSessionId(cookieHeaders));
HttpResponse response = httpClient.execute(httpPost, httpContext);
// Print the response
entity = response.getEntity();
InputStream content1 = (InputStream)entity.getContent();
System.out.println("############### 2nd #####################"+response.getStatusLine().getStatusCode());
BufferedReader in1 =
new BufferedReader (new InputStreamReader (content1));
String line1;
while ((line1 = in1.readLine()) != null) {
System.out.println(line1);
}
// Print the header for 2nd url
org.apache.http.Header[] headers1 = response.getAllHeaders();
System.out.println("##### Header length 2 ::"+headers1.length);
for(int i=0;i<headers1.length; i++)
{
System.out.println("Header Name 2 ::"+headers1[i].getName());
System.out.println("Header Val 2 ::"+headers1[i].getValue());
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
try {
EntityUtils.consume(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
httpClient.getConnectionManager().shutdown();
}
}
private static String getSessionId(org.apache.http.Header[] headers) {
// TODO Auto-generated method stub
for(int i=0;i<headers.length; i++)
{
String str = headers[i].getValue();
String[] strArray = str.split("=");
String[] cookieValueArray = strArray[1].split(";");
System.out.println(strArray[0]+"|"+cookieValueArray[0]);
if(strArray[0].startsWith("J2EEJSESSION"))
{
System.out.println("cookieValueArray[0]:"+cookieValueArray[0]);
return cookieValueArray[0];
}
}
return null;
}
protected CookieStore updateCookieStore(org.apache.http.Header[] headers, CookieStore cookieStore)
{
for(int i=0;i<headers.length; i++)
{
String str = headers[i].getValue();
String[] strArray = str.split("=");
String[] cookieValueArray = strArray[1].split(";");
System.out.println(strArray[0]+"|"+cookieValueArray[0]);
BasicClientCookie cookie = new BasicClientCookie(strArray[0], "A"+cookieValueArray[0]);
/*if(strArray[0].startsWith("J2EEJSESSION"))
{
cookie.setDomain("yyyyy.xxx.com");
}
else
{
cookie.setDomain(".xxx.com");
}*/
cookie.setDomain(".xxx.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
if(strArray[0].startsWith("J2EEJSESSION"))
{
BasicClientCookie cookie1 = new BasicClientCookie("JSESSIONID", "A"+cookieValueArray[0]);
cookie1.setDomain(".xxx.com");
cookie1.setPath("/");
cookieStore.addCookie(cookie1);
}
}
return cookieStore;
}
Another observation:
When i remove the "A" concat from the below snippet, i am not getting the J2EESESSIONID in the 2nd hit:
BasicClientCookie cookie = new BasicClientCookie(strArray[0], "A"+cookieValueArray[0]);
Found the answer on the same day I posted this question.. thought of sharing..
The answer is very simple.. For some reasons the authentication wasn't successful, hence the new jsessionId was created. Replaced "httpClient.getCredentialsProvider().setCredentials()" with "BasicNameValuePair" and it worked :)