I want to make an http post request using webview.
webView.setWebViewClient(new WebViewClient(){
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
public boolean shouldOverrideUrlLoading(WebView view,
String url) {
webView.postUrl(Base_Url, postData.getBytes());
return true;
}
});
The above code snippet loads the webpage. I want to access the response of this request.
How can i obtain the response of an http post request using webview?
Thanks in Advance
First add the support of the http library to your gradle file:
To be able to use
useLibrary 'org.apache.http.legacy'
After this you can use the following code to perform post request in your webview:
public void postUrl (String url, byte[] postData)
String postData = "submit=1&id=236";
webview.postUrl("http://www.belencruzz.com/exampleURL",EncodingUtils.getBytes(postData, "BASE64"));
http://belencruz.com/2012/12/do-post-request-on-a-webview-in-android/
The WebView does not let you access the content of the HTTP response.
You have to use HttpClient for that, and then forward the content to the view by using the function loadDataWithBaseUrl and specifying the base url so that the user can use the webview to continue navigating in the website.
Example:
// Executing POST request
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(postContent);
HttpResponse response = httpclient.execute(httppost);
// Get the response content
String line = "";
StringBuilder contentBuilder = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((line = rd.readLine()) != null) {
contentBuilder.append(line);
}
String content = contentBuilder.toString();
// Do whatever you want with the content
// Show the web page
webView.loadDataWithBaseURL(url, content, "text/html", "UTF-8", null);
Related
I need to post data to server (with "referer" header field) and load the response in Webview.
Now, there are different methods (from Android WebView) to do parts of it, like there is:
void loadUrl(String url, Map<String, String> additionalHttpHeaders)
Loads the given URL with the specified additional HTTP headers.
void loadData(String data, String mimeType, String encoding)
Loads the given data into this WebView using a 'data' scheme URL.
void postUrl(String url, byte[] postData)
Loads the URL with postData using "POST" method into this WebView.
loadUrl() allows to send HttpHeaders but doesn't allow to send post data, other methods seem to be not allowing to send HttpHeaders. Am I missing something or what I am trying is not possible?
You can execute the HttpPost manually like this:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/postreceiver");
// generating your data (AKA parameters)
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("ParameterName", "ParameterValue"));
// ...
// adding your headers
httppost.setHeader("HeaderName", "HeaderValue");
// ...
// adding your data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Get the response as String:
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
String html = builder.toString();
Now you can put the html into yourWebView by using loadData():
yourWebView.loadData(html ,"text/html", "UTF-8");
You can use a custom class that inherits from WebView, or if you prefer, you can add an extension function. The logic is essentially the same:
private fun WebView.postUrl(postUrl: String, postData: ByteArray, additionalHttpHeaders: MutableMap<String, String>) {
val savedWebViewClient = getWebViewClient()
webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {
if (url != postUrl) {
view.post {
webViewClient = savedWebViewClient
}
return savedWebViewClient?.shouldInterceptRequest(view, url)
}
Log.d("WebView extension", "post ${postData.decodeToString()} to ${url}")
val httpsUrl = URL(url)
val conn: HttpsURLConnection = httpsUrl.openConnection() as HttpsURLConnection
conn.requestMethod = "POST"
additionalHttpHeaders.forEach { header ->
conn.addRequestProperty(header.key, header.value)
}
conn.outputStream.write(postData)
conn.outputStream.close()
val responseCode = conn.responseCode
Log.d("WebView extension", "responseCode = ${responseCode} ${conn.contentType}")
view.post {
webViewClient = savedWebViewClient
}
// typical conn.contentType is "text/html; charset=UTF-8"
return WebResourceResponse(conn.contentType.substringBefore(";"), "utf-8", conn.inputStream)
}
}
loadUrl(postUrl, additionalHttpHeaders)
}
The code above was redacted for brevity, with most error checking hidden. To work for API below level 26, I use reflection to extract the savedWebViewClient.
In real life, you also want to override the new shouldInterceptRequest(view: WebView, request: WebResourceRequest) method, and delegate all other methods of your WebViewClient to the savedWebViewClient. Probably a PostWithHeadersWebView class (which overrides also setWibViewClient()) could make your life easier.
So, I have this webpage which I want to access, but first I have to login from another webpage. I want to keep the cookies and then use it for later automatic login. So far what I did:
First, this is the login webpage: https://autenticacao.uvanet.br/autenticacao/pages/login.jsf
It's my university's student's area.
public class Consulta extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
StringBuilder builder = new StringBuilder(100000);
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(urls[0]);
try {
List<NameValuePair> val = new ArrayList<NameValuePair>(2);
val.add(new BasicNameValuePair("form:usuario", "myusername"));
val.add(new BasicNameValuePair("form:senha", "mypass"));
httpPost.setEntity(new UrlEncodedFormEntity(val));
HttpResponse response = client.execute(httpPost);
InputStream content = response.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
builder.append(s);
}
} catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
}
This is the class I use to make the HttpPost and this is how I call it:
#Override
public void onClick(View v) {
try{
String html = new Consulta().execute("https://autenticacao.uvanet.br/autenticacao/pages/login.jsf").get();
Document doc = Jsoup.parse(html);
Element link = doc.select("title").first();
String t = link.text();
tv1.setText(t);
}catch(Exception e){
e.printStackTrace();
}
}
I believed it would work this way:
I send the webpage to login to Consulta.java
The class would get the fields "form:usuario" and "form:senha" and fill them with myusername and mypassword and then login
The class would return me html code of the second webpage as string
But what happens is that it returns me the first webpage (the login one). I'm pretty sure I'm doing something wrong, but I don't know what, could someone help me? Also, sorry for my english, it's not my main language.
When you do the login (in https://autenticacao.uvanet.br/autenticacao/pages/login.jsf), I don't think the response is the html code of the second webpage. Are you sure about this?
I think the normal behavior for a login page is to respond with the same page (the login one) but adding the session cookie and the header to do a redirect to the second webpage, but not the second page itself.
In this case, you have to read the http header response to extract these parameters: the cookies and the URL of the second webpage.
Using the object HttpResponse:
Header[] h = response.getAllHeaders();
But I recommend you to use HttpURLConnection class instead of DefaultHttpClient.
I need to post data to server (with "referer" header field) and load the response in Webview.
Now, there are different methods (from Android WebView) to do parts of it, like there is:
void loadUrl(String url, Map<String, String> additionalHttpHeaders)
Loads the given URL with the specified additional HTTP headers.
void loadData(String data, String mimeType, String encoding)
Loads the given data into this WebView using a 'data' scheme URL.
void postUrl(String url, byte[] postData)
Loads the URL with postData using "POST" method into this WebView.
loadUrl() allows to send HttpHeaders but doesn't allow to send post data, other methods seem to be not allowing to send HttpHeaders. Am I missing something or what I am trying is not possible?
You can execute the HttpPost manually like this:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/postreceiver");
// generating your data (AKA parameters)
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("ParameterName", "ParameterValue"));
// ...
// adding your headers
httppost.setHeader("HeaderName", "HeaderValue");
// ...
// adding your data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Get the response as String:
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
String html = builder.toString();
Now you can put the html into yourWebView by using loadData():
yourWebView.loadData(html ,"text/html", "UTF-8");
You can use a custom class that inherits from WebView, or if you prefer, you can add an extension function. The logic is essentially the same:
private fun WebView.postUrl(postUrl: String, postData: ByteArray, additionalHttpHeaders: MutableMap<String, String>) {
val savedWebViewClient = getWebViewClient()
webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {
if (url != postUrl) {
view.post {
webViewClient = savedWebViewClient
}
return savedWebViewClient?.shouldInterceptRequest(view, url)
}
Log.d("WebView extension", "post ${postData.decodeToString()} to ${url}")
val httpsUrl = URL(url)
val conn: HttpsURLConnection = httpsUrl.openConnection() as HttpsURLConnection
conn.requestMethod = "POST"
additionalHttpHeaders.forEach { header ->
conn.addRequestProperty(header.key, header.value)
}
conn.outputStream.write(postData)
conn.outputStream.close()
val responseCode = conn.responseCode
Log.d("WebView extension", "responseCode = ${responseCode} ${conn.contentType}")
view.post {
webViewClient = savedWebViewClient
}
// typical conn.contentType is "text/html; charset=UTF-8"
return WebResourceResponse(conn.contentType.substringBefore(";"), "utf-8", conn.inputStream)
}
}
loadUrl(postUrl, additionalHttpHeaders)
}
The code above was redacted for brevity, with most error checking hidden. To work for API below level 26, I use reflection to extract the savedWebViewClient.
In real life, you also want to override the new shouldInterceptRequest(view: WebView, request: WebResourceRequest) method, and delegate all other methods of your WebViewClient to the savedWebViewClient. Probably a PostWithHeadersWebView class (which overrides also setWibViewClient()) could make your life easier.
I need to post data to server (with "referer" header field) and load the response in Webview.
Now, there are different methods (from Android WebView) to do parts of it, like there is:
void loadUrl(String url, Map<String, String> additionalHttpHeaders)
Loads the given URL with the specified additional HTTP headers.
void loadData(String data, String mimeType, String encoding)
Loads the given data into this WebView using a 'data' scheme URL.
void postUrl(String url, byte[] postData)
Loads the URL with postData using "POST" method into this WebView.
loadUrl() allows to send HttpHeaders but doesn't allow to send post data, other methods seem to be not allowing to send HttpHeaders. Am I missing something or what I am trying is not possible?
You can execute the HttpPost manually like this:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/postreceiver");
// generating your data (AKA parameters)
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("ParameterName", "ParameterValue"));
// ...
// adding your headers
httppost.setHeader("HeaderName", "HeaderValue");
// ...
// adding your data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Get the response as String:
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
String html = builder.toString();
Now you can put the html into yourWebView by using loadData():
yourWebView.loadData(html ,"text/html", "UTF-8");
You can use a custom class that inherits from WebView, or if you prefer, you can add an extension function. The logic is essentially the same:
private fun WebView.postUrl(postUrl: String, postData: ByteArray, additionalHttpHeaders: MutableMap<String, String>) {
val savedWebViewClient = getWebViewClient()
webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(view: WebView, url: String): WebResourceResponse? {
if (url != postUrl) {
view.post {
webViewClient = savedWebViewClient
}
return savedWebViewClient?.shouldInterceptRequest(view, url)
}
Log.d("WebView extension", "post ${postData.decodeToString()} to ${url}")
val httpsUrl = URL(url)
val conn: HttpsURLConnection = httpsUrl.openConnection() as HttpsURLConnection
conn.requestMethod = "POST"
additionalHttpHeaders.forEach { header ->
conn.addRequestProperty(header.key, header.value)
}
conn.outputStream.write(postData)
conn.outputStream.close()
val responseCode = conn.responseCode
Log.d("WebView extension", "responseCode = ${responseCode} ${conn.contentType}")
view.post {
webViewClient = savedWebViewClient
}
// typical conn.contentType is "text/html; charset=UTF-8"
return WebResourceResponse(conn.contentType.substringBefore(";"), "utf-8", conn.inputStream)
}
}
loadUrl(postUrl, additionalHttpHeaders)
}
The code above was redacted for brevity, with most error checking hidden. To work for API below level 26, I use reflection to extract the savedWebViewClient.
In real life, you also want to override the new shouldInterceptRequest(view: WebView, request: WebResourceRequest) method, and delegate all other methods of your WebViewClient to the savedWebViewClient. Probably a PostWithHeadersWebView class (which overrides also setWibViewClient()) could make your life easier.
I am developing an android application in which I want to fetch the news from a url without opening default browser of android. This means I want to fetch only the texutal content, only news instead of complete html page in browser. How can I do this?
If I understand correctly - you need to make a request online and receive in return the html code.
This is done as follows:
DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(http://example.com/news));
HttpResponse response = client.execute(request);
BufferedReader in = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
String html = sb.toString();
Do you mean that you want to parse the actual content of the webpage to your application? When I did so in one of my apps, I parsed the whole webpage with a simple http://developer.android.com/reference/org/xmlpull/v1/XmlPullParser.html and then I took out those tags which where relevant. This however requires some pretty heavy dynamical programming running under an asynctask (http://developer.android.com/reference/android/os/AsyncTask.html).
URL url = new URL(XML_INIT_ADRESS);
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(url.openStream(), null);
I'm personally not very experienced with Android yet and I'm still learning but you should be able to parse the news from a webpage this way.
Edit: This approach pretty much requires some kind of identification of the certain "news-tags", Antons answer is better if they are "undefinable".
Hi Yes You can implement this.Use This code which i mention below.
- WebView webView = (WebView) findViewById(R.id.webview_btn);
WebSettings settings = webView.getSettings();
mProgress = ProgressDialog.show(this, "Loading", "Please wait for a moment...");
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
WebViewClient client = new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
mProgress.show();
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
if(mProgress.isShowing())
{
mProgress.dismiss();
}
}
};
webView.loadUrl(enter your url);
webView.setWebViewClient(client);
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://www.example.com/" + URL);
response = httpClient.execute(httpGet, localContext);