I am just trying to call an external web-service from my Java AWS Lambda function. To do this I can't get the org.apache.http client to work. I have the code:
public static String get(String get) throws ClientProtocolException, IOException{
RequestConfig defaultRequestConfig = RequestConfig.custom().setExpectContinueEnabled(true).build();
HttpGet httpGetRequest = new HttpGet(get);
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig).setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
httpGetRequest.setConfig(requestConfig);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse httpResponse = httpClient.execute(httpGetRequest); <<<<<
HttpEntity entity = httpResponse.getEntity();
StringBuffer all = new StringBuffer();
if (entity != null) {
InputStream inputStream = entity.getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(new BufferedInputStream(inputStream)));
String read;
while ((read = in.readLine()) != null){
all.append(read);
all.append("\n");
}
httpClient.close();
}
return all.toString();
}
Once it is deployed it hangs on the line HttpResponse httpResponse = httpClient.execute(httpGetRequest); <<<<< above.
I can prove that I have connectivity from the lambda function to the internet by setting up a Socket connection e.g. Socket s = new Socket(InetAddress.getByName("bbc.co.uk"), 80); and I can retrieve data this way.
So the question is either what is wrong with the first code fragment which works locally but not when deployed? or is there a preferred way to call web-services from AWS lambda functions in Java (I have had a search but can't find a best practice) ? I would prefer not to have to hand craft the HTTP requests using Sockets if I can help it.
The issue here is the usage of Apache HttpClient which is a large library. Switching to OkHttp fixed the issue in my case.
Please try to use Rest Template to make this call.
try {
String url = "baseurl for AWS insatnce +8080/Testing/mailGenration/generate?msg=20;
logger.log("Building HttpClient......");
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
logger.log("Response Code : " + response.getStatusLine().getStatusCode());
} catch (Exception e) {
logger.log("Exception in sendhttpclient:" + e);
}
Related
I was asked to look for downloading file using MultiPartEntity in android However i searched a lot but couldn't find any solution where I can download file using MultiPartEntity. it seems it is used to upload files only.
I couldn't find detail description whether it does use for download or not.
so helplessly I had to ask the question on stackoverflow. If it does can anyone share a link or code snippet for the same. If it doesn't Please tell this information too. I'll be really glad.
Thank you very much in advance.
You can download contents of a file from URL as follows,
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost(/*Download URL*/);
/* If you want custom timeout time use this
int TIMEOUT_MILLIS = 1000;
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(TIMEOUT_MILLIS).setConnectTimeout(TIMEOUT_MILLIS).setConnectionRequestTimeout(TIMEOUT_MILLIS).build();
*/
RequestConfig requestConfig = RequestConfig.DEFAULT;
httpPost.setConfig(requestConfig);
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
HttpEntity httpEntity = builder.build();
httpPost.setEntity(httpEntity);
HttpResponse response = httpClient.execute(httpPost);
String responseLine = null;
if (response != null && response.getStatusLine().getStatusCode() == 200) {
BufferedReader bufferedReader = null;
InputStreamReader streamReader = null;
String line = null;
try {
streamReader = new InputStreamReader(response.getEntity().getContent());
bufferedReader = new BufferedReader(streamReader);
StringBuilder responseBuilder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
responseBuilder.append(line);
}
responseLine = responseBuilder.toString();
} catch (Exception exception) {
//Handle Exceptions
} finally {
bufferedReader.close();
streamReader.close();
}
}
I have this code, who should connect to a php remote file and should get a String representing a XML file. But something is wrong, it is giving me error 401.
The variable url is the direction of the php:
String response=getXML("http://ficticiousweb.com/scripts/getMagazinesList.php");
If i paste the real direction (that is a ficticious direction) on the webbrowser, it works and gives me the XML.
This is my code:
public String getXML(String url){
try{
StringBuilder builder = new StringBuilder();
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpclient.execute(httpget);
int statuscode = response.getStatusLine().getStatusCode();
if(statuscode == 200)
{
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) builder.append(line);
}
else throw new Exception("HTTP error: " + String.valueOf(statuscode));
return builder.toString();
}catch(Exception e){e.printStackTrace();}
return null;
}
What is wrong with the code?
thanks
You need to login to the requested site in order to download or access the xml. This can be done by authenticated schema based upon what is supported. Normally, there are 2 types of schemas where used. Basic and Digest. Below code will help you for BASIC AUTH.
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String _username = "username";
String _password = "password";
try {
((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials(
new org.apache.http.auth.AuthScope(webhostname, webport)),
new org.apache.http.auth.UsernamePasswordCredentials(_username, _password));
response = httpclient.execute(new HttpGet(completeurlhere));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK) {
try {
InputStream is = response.getEntity().getContent();
this._data = is;
} catch(Exception ex) {
Log.e("DBF Error",ex.toString());
}
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch(ClientProtocolException cpe) {
Log.e("ClientProtocolException # at FPT",cpe.toString());
} catch(Exception ex) {
Log.e("Exception at FETCHPROJECTASK",ex.toString());
}
Well a 401 means you aren't Authorized to do the GET request. You should ask the website how to Authenticate the request...
Authorization happens through the Authorization Header in the HTTP request. You should look into that and probably fill that header yourself with your credentials... (if the server accepts that)
I'm attempting to receive a response from a restful service, but receive a timeout. I am able to connect with the browser on my emulator, as I have configured an access point on the emulated device to pass through proxy (at work). Network seems to be fine. I've added:
<uses-permission android:name="android.permission.INTERNET" />
to the AndroidManifest.xml file.
The code is as follows:
public String getInputStreamFromUrl(String url) {
String content = null;
InputStream stream = null;
try {
HttpGet httpGet = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
// Execute HTTP Get Request
HttpResponse response = httpclient.execute(httpGet);
stream = response.getEntity().getContent();
BufferedReader rd = new BufferedReader(new InputStreamReader(stream), 4096);
String line;
StringBuilder sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
content = sb.toString();
} catch (Exception e) {
content = e.getMessage();
}
return content;
I know I should return a stream, but for the sake of just displaying some string values in a TextView widget, will suffice, so I'm just using the string to experiment. It consistently hangs on .execute, no matter what URL is passed. I've passed valid IP's as well, with nothin' doin'.
I appreciate your help in advance.
Try this. Put it at the top of the class.
System.setProperty("http.proxyHost", <your proxy host name>);
System.setProperty("http.proxyPort", <your proxy port>);
I'm POSTing some data to a server that is answering a 302 Moved Temporarily.
I want HttpClient to follow the redirect and automatically GET the new location, as I believe it's the default behaviour of HttpClient. However, I'm getting an exception and not following the redirect :(
Here's the relevant piece of code, any ideas will be appreciated:
HttpParams httpParams = new BasicHttpParams();
HttpClientParams.setRedirecting(httpParams, true);
SchemeRegistry schemeRegistry = registerFactories();
ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(clientConnectionManager, httpParams)
HttpPost postRequest = new HttpPost(url);
postRequest.setHeader(HTTP.CONTENT_TYPE, contentType);
postRequest.setHeader(ACCEPT, contentType);
if (requestBodyString != null) {
postRequest.setEntity(new StringEntity(requestBodyString));
}
return httpClient.execute(postRequest, responseHandler);
For HttpClient 4.3:
HttpClient instance = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy()).build();
For HttpClient 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new LaxRedirectStrategy());
For HttpClient < 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new DefaultRedirectStrategy() {
/** Redirectable methods. */
private String[] REDIRECT_METHODS = new String[] {
HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME
};
#Override
protected boolean isRedirectable(String method) {
for (String m : REDIRECT_METHODS) {
if (m.equalsIgnoreCase(method)) {
return true;
}
}
return false;
}
});
The default behaviour of HttpClient is compliant with the requirements of the HTTP specification (RFC 2616)
10.3.3 302 Found
...
If the 302 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
You can override the default behaviour of HttpClient by sub-classing DefaultRedirectStrategy and overriding its #isRedirected() method.
It seem http redirect is disable by default. I try to enable, it work but I'm still got error with my problem. But we still can handle redirection pragmatically. I think your problem can solve:
So old code:
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("User-Agent");
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
long contentSize = httpResponse.getEntity().getContentLength();
This code will return contentSize = -1 if http redirect happend
And then I handle redirect by myself after trying enable default follow redirection
AndroidHttpClient client;
HttpGet httpGet;
HttpResponse response;
HttpHeader httpHeader;
private void handleHTTPRedirect(String url) throws IOException {
if (client != null)
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(url));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
while (httpHeader.length > 0) {
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(httpHeader[0].getValue()));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
}
}
In use
handleHTTPRedirect(url);
long contentSize = httpResponse.getEntity().getContentLength();
Thanks
Nguyen
My solution is using HttClient. I had to send the response back to the caller. This is my solution
CloseableHttpClient httpClient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
//this reads the input stream from POST
ServletInputStream str = request.getInputStream();
HttpPost httpPost = new HttpPost(path);
HttpEntity postParams = new InputStreamEntity(str);
httpPost.setEntity(postParams);
HttpResponse httpResponse = null ;
int responseCode = -1 ;
StringBuffer response = new StringBuffer();
try {
httpResponse = httpClient.execute(httpPost);
responseCode = httpResponse.getStatusLine().getStatusCode();
logger.info("POST Response Status:: {} for file {} ", responseCode, request.getQueryString());
//return httpResponse ;
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
logger.info(" Final Complete Response {} " + response.toString());
httpClient.close();
} catch (Exception e) {
logger.error("Exception ", e);
} finally {
IOUtils.closeQuietly(httpClient);
}
// Return the response back to caller
return new ResponseEntity<String>(response.toString(), HttpStatus.ACCEPTED);
For HttpClient v5, just use the below:
httpClient = HttpClientBuilder.create()
.setRedirectStrategy(new DefaultRedirectStrategy() {
#Override
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
throws ProtocolException {
return false;
}
}).build();
I log on to a website using the POST method (httpclient from apache).
I let the HttpClient execute the HttpPost, let the connection manager release it and then I want to post a GET message that opens a php-URL file to download a pdf.
But all I get is the html file of a "session expired" page
(println: File: index_GT_neu.html?fehlermeldung=fehler_sessioncheck)
I was thinking that once i used the instance of HttpClient to log on at the site, I would be able to open another URL that is only available after log on. But appearently I was wrong.
Somebody could give me a hint?
Thanks in advance!
This is what my main looks like:
// prepare post method
HttpPost post = new HttpPost("http://epaper02.niedersachsen.com/epaper/index_GT_neu.html");
//prepare get method
HttpGet httpget = new HttpGet("http://epaper01.niedersachsen.com/epaper/getfile.php?pdf=0114_GTB_HP_01.pdf&zeitung=GT&ekZeitung=&Y=11&M=01&D=14&C=0");
// add parameters to the post method
List <NameValuePair> parameters = new ArrayList <NameValuePair>();
parameters.add(new BasicNameValuePair("username", "test"));
parameters.add(new BasicNameValuePair("passwort", "test"));
UrlEncodedFormEntity sendentity = new UrlEncodedFormEntity(parameters, HTTP.UTF_8);
post.setEntity(sendentity);
// create the client and execute the post method
HttpClient client = new DefaultHttpClient();
HttpResponse postResponse = client.execute(post);
//Output the Response from the POST
System.out.print(convertInputStreamToString(postResponse.getEntity().getContent()));
//releasing POST
EntityUtils.consume(postResponse.getEntity());
//Execute get
HttpContext context = new BasicHttpContext();
HttpResponse getResponse = client.execute(httpget, context);
System.out.println("Statusline: " + getResponse.getStatusLine());
if (getResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
throw new IOException(getResponse.getStatusLine().toString());
HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
String currentUrl = URLDecoder.decode(currentReq.getURI().toString(), "UTF-8");
int i = currentUrl.lastIndexOf('/');
String fileName = null;
if (i < 0) {
fileName = currentUrl;
} else {
fileName = currentUrl.substring(i + 1);
}
System.out.println("File: " + fileName);
//Create file
OutputStream os = new FileOutputStream( fileName);
InputStream is = getResponse.getEntity().getContent();
byte[] buf = new byte[4096];
int read;
while ((read = is.read(buf)) != -1) {
os.write(buf, 0, read);
}
os.close();
client.getConnectionManager().shutdown();
By default, DefaultHttpClient does not have a cookie store. A cookie store is needed in order to store cookies that are populated initially or that are obtained while interacting with the HTTP client. As soon as digging into this topic you will start to think about the scope/sharing of cookies.
You can enable the cookie store with one additional line of code:
DefaultHttpClient client = new DefaultHttpClient();
client.setCookieStore(new BasicCookieStore());
I know, this might be a bit late, still HTH.
I am not familiar with this library but try creating context before calling the post and reuse the same context for the get:
HttpContext context = new BasicHttpContext();
// create the client and execute the post method
HttpClient client = new DefaultHttpClient();
HttpResponse postResponse = client.execute(post,context);
...
HttpResponse getResponse = client.execute(httpget, context);