How to call `POST` RESTfull methods in Android? - java

I have developed a web service in Java. Below is a method of it.
#Path("/setup")
public class SetupJSONService {
#POST
#Path("/insertSetup")
#Consumes(MediaType.APPLICATION_JSON)
public String insertSetup(SetupBean bean)
{
System.out.println("Printed");
SetupInterface setupInterface = new SetupImpl();
String insertSetup = setupInterface.insertSetup(bean);
return insertSetup;
}
}
Below is how I call this method using Java Jersey in my computer.
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/TestApp/rest/setup").path("/insertSetup");
SetupBean setupBean = new SetupBean();
setupBean.setIdPatient(1);
setupBean.setCircleType(1);
target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(setupBean, MediaType.APPLICATION_JSON_TYPE));
However, Now this method should be called in Android as well, but I'm not sure how to do that. I know how to make GET calls in android like below.
public static String httpGet(String urlStr) throws IOException {
URL url = new URL(urlStr);
HttpURLConnection conn =
(HttpURLConnection) url.openConnection();
if (conn.getResponseCode() != 200) {
throw new IOException(conn.getResponseMessage());
}
// Buffer the result into a string
BufferedReader rd = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
return sb.toString();
}
But since my method is POST and since it accept a Java Bean and it does return a String, how can I handle this in Android? Not interested using Jersey in android as it does have bad comments in Android environment.

Android provides a way to do what you want, but this is not a productive way, i like to use retrofit 2 to power my development and to write a better code.
Here a example of retrofit 2 that can help you =) :
add to your dependencies in build.gradle
dependencies {
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
}
Create your retrofit builder that specifies a converter and a base url.
public static final String URL = "http://localhost:8080/TestApp/rest/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Now create a Interface that will encapsulate your rest methods like below
public interface YourEndpoints {
#POST("setup/insertSetup")
Call<ResponseBody> insertSetup(#Body SetupBean setupBean);
}
Associate your endpoints interface with your retrofit instance.
YourEndpoints request = retrofit.create(YourEndpoints.class);
Call<ResponseBody> yourResult = request.insertSetup(YourSetupBeanObject);
yourResult.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//response.code()
//your string response response.body().string()
}
#Override
public void onFailure(Throwable t) {
//do what you have to do if it return a error
}
});
Ref to this links for more information:
http://square.github.io/retrofit/
https://github.com/codepath/android_guides/wiki/Consuming-APIs-with-Retrofit

that`s the code for the normal way you want
InputStream is = null;
OutputStream os = null;
HttpURLConnection con = null;
try {
//constants
URL url = new URL("http://localhost:8080/TestApp/rest/");
//Map your object to JSONObject and convert it to a json string
String message = new JSONObject().toString();
con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(1000);
con.setConnectTimeout(15000);
con.setRequestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);
con.setFixedLengthStreamingMode(message.getBytes().length);
con.setRequestProperty("Content-Type", "application/json;charset=utf-8");
//open
con.connect();
//setup send
os = new BufferedOutputStream(con.getOutputStream());
os.write(message.getBytes());
//clean up
os.flush();
//do somehting with response
is = con.getInputStream();
String contentAsString = readData(is,len);
os.close();
is.close();
con.disconnect();
} catch (Exception e){
try {
os.close();
is.close();
con.disconnect();
} catch (IOException e1) {
e1.printStackTrace();
}
}

Related

Which packages can I use for sending and receiving messages (Communicating) through internet [duplicate]

I have searched everywhere but I couldn't find my answer, is there a way to make a simple HTTP request? I want to request a PHP page / script on one of my websites but I don't want to show the webpage.
If possible I even want to do it in the background (in a BroadcastReceiver)
UPDATE
This is a very old answer. I definitely won't recommend Apache's client anymore. Instead use either:
Retrofit
OkHttp
Volley
HttpUrlConnection
Original Answer
First of all, request a permission to access network, add following to your manifest:
<uses-permission android:name="android.permission.INTERNET" />
Then the easiest way is to use Apache http client bundled with Android:
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(URL));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
String responseString = out.toString();
out.close();
//..more logic
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
If you want it to run on separate thread I'd recommend extending AsyncTask:
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
responseString = out.toString();
out.close();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
You then can make a request by:
new RequestTask().execute("http://stackoverflow.com");
unless you have an explicit reason to choose the Apache HttpClient, you should prefer java.net.URLConnection. you can find plenty of examples of how to use it on the web.
we've also improved the Android documentation since your original post: http://developer.android.com/reference/java/net/HttpURLConnection.html
and we've talked about the trade-offs on the official blog: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
Note: The Apache HTTP Client bundled with Android is now deprecated in favor of HttpURLConnection. Please see the Android Developers Blog for more details.
Add <uses-permission android:name="android.permission.INTERNET" /> to your manifest.
You would then retrieve a web page like so:
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
}
finally {
urlConnection.disconnect();
}
I also suggest running it on a separate thread:
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
String responseString = null;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){
// Do normal input or output stream reading
}
else {
response = "FAILED"; // See documentation for more info on response handling
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
See the documentation for more information on response handling and POST requests.
The most simple way is using the Android lib called Volley
Volley offers the following benefits:
Automatic scheduling of network requests. Multiple concurrent network
connections. Transparent disk and memory response caching with
standard HTTP cache coherence. Support for request prioritization.
Cancellation request API. You can cancel a single request, or you can
set blocks or scopes of requests to cancel. Ease of customization, for
example, for retry and backoff. Strong ordering that makes it easy to
correctly populate your UI with data fetched asynchronously from the
network. Debugging and tracing tools.
You can send a http/https request as simple as this:
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.yourapi.com";
JsonObjectRequest request = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (null != response) {
try {
//handle your response
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(request);
In this case, you needn't consider "running in the background" or "using cache" yourself as all of these has already been done by Volley.
Use Volley as suggested above. Add following into build.gradle (Module: app)
implementation 'com.android.volley:volley:1.1.1'
Add following into AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
And add following to you Activity code:
public void httpCall(String url) {
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// enjoy your response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// enjoy your error status
}
});
queue.add(stringRequest);
}
It replaces http client and it is very simple.
private String getToServer(String service) throws IOException {
HttpGet httpget = new HttpGet(service);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
return new DefaultHttpClient().execute(httpget, responseHandler);
}
Regards
With a thread:
private class LoadingThread extends Thread {
Handler handler;
LoadingThread(Handler h) {
handler = h;
}
#Override
public void run() {
Message m = handler.obtainMessage();
try {
BufferedReader in =
new BufferedReader(new InputStreamReader(url.openStream()));
String page = "";
String inLine;
while ((inLine = in.readLine()) != null) {
page += inLine;
}
in.close();
Bundle b = new Bundle();
b.putString("result", page);
m.setData(b);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
handler.sendMessage(m);
}
}
As none of the answers described a way to perform requests with OkHttp, which is very popular http client nowadays for Android and Java in general, I am going to provide a simple example:
//get an instance of the client
OkHttpClient client = new OkHttpClient();
//add parameters
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://www.example.com").newBuilder();
urlBuilder.addQueryParameter("query", "stack-overflow");
String url = urlBuilder.build().toString();
//build the request
Request request = new Request.Builder().url(url).build();
//execute
Response response = client.newCall(request).execute();
The clear advantage of this library is that it abstracts us from some low level details, providing more friendly and secure ways to interact with them. The syntax is also simplified and permits to write nice code.
I made this for a webservice to requerst on URL, using a Gson lib:
Client:
public EstabelecimentoList getListaEstabelecimentoPorPromocao(){
EstabelecimentoList estabelecimentoList = new EstabelecimentoList();
try{
URL url = new URL("http://" + Conexao.getSERVIDOR()+ "/cardapio.online/rest/recursos/busca_estabelecimento_promocao_android");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
if (con.getResponseCode() != 200) {
throw new RuntimeException("HTTP error code : "+ con.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((con.getInputStream())));
estabelecimentoList = new Gson().fromJson(br, EstabelecimentoList.class);
con.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return estabelecimentoList;
}
Look at this awesome new library which is available via gradle :)
build.gradle: compile 'com.apptakk.http_request:http-request:0.1.2'
Usage:
new HttpRequestTask(
new HttpRequest("http://httpbin.org/post", HttpRequest.POST, "{ \"some\": \"data\" }"),
new HttpRequest.Handler() {
#Override
public void response(HttpResponse response) {
if (response.code == 200) {
Log.d(this.getClass().toString(), "Request successful!");
} else {
Log.e(this.getClass().toString(), "Request unsuccessful: " + response);
}
}
}).execute();
https://github.com/erf/http-request
This is the new code for HTTP Get/POST request in android. HTTPClient is depricated and may not be available as it was in my case.
Firstly add the two dependencies in build.gradle:
compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'
Then write this code in ASyncTask in doBackground method.
URL url = new URL("http://localhost:8080/web/get?key=value");
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
InputStream it = new BufferedInputStream(urlConnection.getInputStream());
InputStreamReader read = new InputStreamReader(it);
BufferedReader buff = new BufferedReader(read);
StringBuilder dta = new StringBuilder();
String chunks ;
while((chunks = buff.readLine()) != null)
{
dta.append(chunks);
}
}
else
{
//Handle else
}
For me, the easiest way is using library called Retrofit2
We just need to create an Interface that contain our request method, parameters, and also we can make custom header for each request :
public interface MyService {
#GET("users/{user}/repos")
Call<List<Repo>> listRepos(#Path("user") String user);
#GET("user")
Call<UserDetails> getUserDetails(#Header("Authorization") String credentials);
#POST("users/new")
Call<User> createUser(#Body User user);
#FormUrlEncoded
#POST("user/edit")
Call<User> updateUser(#Field("first_name") String first,
#Field("last_name") String last);
#Multipart
#PUT("user/photo")
Call<User> updateUser(#Part("photo") RequestBody photo,
#Part("description") RequestBody description);
#Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
#GET("users/{username}")
Call<User> getUser(#Path("username") String username);
}
And the best is, we can do it asynchronously easily using enqueue method

Should I use HttpURLConnection or RestTemplate [duplicate]

This question already has an answer here:
RestTemplate vs Apache Http Client for production code in spring project
(1 answer)
Closed 4 years ago.
Should I use HttpURLConnection in a Spring Project Or better to use RestTemplate ?
In other words, When it is better to use each ?
The HttpURLConnection and RestTemplate are different kind of beasts. They operate on different abstraction levels.
The RestTemplate helps to consume REST api and the HttpURLConnection works with HTTP protocol.
You're asking what is better to use. The answer depends on what you're trying to achieve:
If you need to consume REST api then stick with RestTemplate
If you need to work with http protocol then use HttpURLConnection, OkHttpClient, Apache's HttpClient, or if you're using Java 11 you can try its HttpClient.
Moreover the RestTemplate uses HttpUrlConnection/OkHttpClient/... to do its work (see ClientHttpRequestFactory, SimpleClientHttpRequestFactory, OkHttp3ClientHttpRequestFactory
Why you should not use HttpURLConnection?
It's better to show some code:
In examples below JSONPlaceholder used
Let's GET a post:
public static void main(String[] args) {
URL url;
try {
url = new URL("https://jsonplaceholder.typicode.com/posts/1");
} catch (MalformedURLException e) {
// Deal with it.
throw new RuntimeException(e);
}
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) url.openConnection();
try (InputStream inputStream = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(isr)) {
// Wrap, wrap, wrap
StringBuilder response = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
response.append(line);
}
// Here is the response body
System.out.println(response.toString());
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
Now let's POST a post something:
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-type", "application/json; charset=UTF-8");
try (OutputStream os = connection.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter wr = new BufferedWriter(osw)) {
wr.write("{\"title\":\"foo\", \"body\": \"bar\", \"userId\": 1}");
}
If the response needed:
try (InputStream inputStream = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(isr)) {
// Wrap, wrap, wrap
StringBuilder response = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
response.append(line);
}
System.out.println(response.toString());
}
As you can see the api provided by the HttpURLConnection is ascetic.
You always have to deal with "low-level" InputStream, Reader, OutputStream, Writer, but fortunately there are alternatives.
The OkHttpClient
The OkHttpClient reduces the pain:
GETting a post:
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url("https://jsonplaceholder.typicode.com/posts/1")
.build();
Call call = okHttpClient.newCall(request);
try (Response response = call.execute();
ResponseBody body = response.body()) {
String string = body.string();
System.out.println(string);
} catch (IOException e) {
throw new RuntimeException(e);
}
POSTing a post:
Request request = new Request.Builder()
.post(RequestBody.create(MediaType.parse("application/json; charset=UTF-8"),
"{\"title\":\"foo\", \"body\": \"bar\", \"userId\": 1}"))
.url("https://jsonplaceholder.typicode.com/posts")
.build();
Call call = okHttpClient.newCall(request);
try (Response response = call.execute();
ResponseBody body = response.body()) {
String string = body.string();
System.out.println(string);
} catch (IOException e) {
throw new RuntimeException(e);
}
Much easier, right?
Java 11's HttpClient
GETting the posts:
HttpClient httpClient = HttpClient.newHttpClient();
HttpResponse<String> response = httpClient.send(HttpRequest.newBuilder()
.uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSTing a post:
HttpResponse<String> response = httpClient.send(HttpRequest.newBuilder()
.header("Content-Type", "application/json; charset=UTF-8")
.uri(URI.create("https://jsonplaceholder.typicode.com/posts"))
.POST(HttpRequest.BodyPublishers.ofString("{\"title\":\"foo\", \"body\": \"barzz\", \"userId\": 2}"))
.build(), HttpResponse.BodyHandlers.ofString());
The RestTemplate
According to its javadoc:
Synchronous client to perform HTTP requests, exposing a simple, template method API over underlying HTTP client libraries such as the JDK {#code HttpURLConnection}, Apache HttpComponents, and others.
Lets do the same
Firstly for convenience the Post class is created. (When the RestTemplate will read the response it will transform it to a Post using HttpMessageConverter)
public static class Post {
public long userId;
public long id;
public String title;
public String body;
#Override
public String toString() {
return new ReflectionToStringBuilder(this)
.toString();
}
}
GETting a post.
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Post> entity = restTemplate.getForEntity("https://jsonplaceholder.typicode.com/posts/1", Post.class);
Post post = entity.getBody();
System.out.println(post);
POSTing a post:
public static class PostRequest {
public String body;
public String title;
public long userId;
}
public static class CreatedPost {
public String body;
public String title;
public long userId;
public long id;
#Override
public String toString() {
return new ReflectionToStringBuilder(this)
.toString();
}
}
public static void main(String[] args) {
PostRequest postRequest = new PostRequest();
postRequest.body = "bar";
postRequest.title = "foo";
postRequest.userId = 11;
RestTemplate restTemplate = new RestTemplate();
CreatedPost createdPost = restTemplate.postForObject("https://jsonplaceholder.typicode.com/posts/", postRequest, CreatedPost.class);
System.out.println(createdPost);
}
So to answer your question:
When it is better to use each ?
Need to consume REST api? Use RestTemplate
Need to work with http? Use some HttpClient.
Also worth mentioning:
Retrofit
Intro to Feign
Declarative REST client

Posting multipart form data via Android AsyncTask

My issue is with the writeArgsToConn() function.....i think. I cant figure out how to implement it.
I am trying to post multipart-formdata from an Android device using AsyncTask class. Can anyone help with this? I want to stay away from the depreciated org.apache.http.legacy stuff and stick with up-to-date Android libraries.
I was able to use similar implementation for a class called DoPostJSON which used Content-Type: application/json and that class works fine.
Same question but on Reddit: https://redd.it/49qqyq
I had issues with getting nodejs express server to detect the parameters being sent in. My DoPostJSON class worked fine and my nodejs server was able to detect parameters...for some reason DoPostMultiPart doesnt work and nodejs server cant see paramters being passed in. I feel like I am using the library the wrong way.
public class DoPostMultiPart extends AsyncTask<JSONObject, Void, JSONObject> implements Post{
#Override
public HttpURLConnection createConn(String action) throws Exception{
URL url = new URL(Utils.host_api + action);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setReadTimeout(35000);
conn.setConnectTimeout(35000);
return conn;
}
#Override
public JSONObject getResponse(HttpURLConnection conn) throws Exception {
int responseCode = conn.getResponseCode();
String response = "";
if (responseCode == HttpsURLConnection.HTTP_OK) {
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(in));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
stringBuilder.append(line).append("\n");
responseStreamReader.close();
response = stringBuilder.toString();
} else {
throw new Exception("response code: " + responseCode);
}
conn.disconnect();
return new JSONObject(response);
}
// TODO: fix this function
#Override
public void writeArgsToConn(JSONObject args, HttpURLConnection conn) throws Exception {
// define paramaters
String fullname = args.getString("fullname");
String email = args.getString("email");
String password = args.getString("password");
String confpassword = args.getString("confpassword");
Bitmap pic = (Bitmap) args.get("pic");
// plugin paramters into request
OutputStream os = conn.getOutputStream();
// how do I plugin the String paramters???
pic.compress(Bitmap.CompressFormat.JPEG, 100, os); // is this right???
os.flush();
os.close();
}
#Override
protected JSONObject doInBackground(JSONObject... params) {
JSONObject args = params[0];
try {
String action = args.getString("action");
HttpURLConnection conn = createConn(action);
writeArgsToConn(args, conn);
return getResponse(conn);
} catch (Exception e) {
Utils.logStackTrace(e);
return null;
}
}
}
I solved my issue by using OkHttpClient library.
JSONObject args = params[0];
try
{
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("fullname", args.getString("fullname"))
.addFormDataPart("email", args.getString("email"))
.addFormDataPart("password", args.getString("password"))
.addFormDataPart("confpassword", args.getString("confpassword"))
.addFormDataPart("pic", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, (File) args.get("pic")))
.build();
Request request = new Request.Builder()
.url(Utils.host_api + args.getString("action"))
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
return new JSONObject(response.body().string());
}
catch (Exception e)
{
Utils.logStackTrace(e);
return null;
}

Invoking servlet from java main method

import java.net.*;
import java.io.*;
public class sample
{
public static void main (String args[])
{
String line;
try
{
URL url = new URL( "http://localhost:8080/WeighPro/CommPortSample" );
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
line = in.readLine();
System.out.println( line );
in.close();
}
catch (Exception e)
{
System.out.println("Hello Project::"+e.getMessage());
}
}
}
My Servlet is invoking another Jsp page like the below,
RequestDispatcher rd=request.getRequestDispatcher("index.jsp");
rd.forward(request, response);
I am not getting any reaction/output in the browser, where the servlet has to be executed once it is invoked.
Am I missing any basic step for this process? Please Help!!!
If you want to open it in browser try this
java.awt.Desktop.getDesktop().browse(java.net.URI.create("http://localhost:8080/WeighPro/CommPortSample"));
You question is not clear. Do you actually want to invoke a Servlet from the Main method, or do you want to make an HTTP request to your web application?
If you want to make an HTTP request, I can't see any obvious problems with your code above, which makes me believe that the problem is in the Servlet. You also mention that you don't get anything in the browser, but running your program above does not involve a browser.
Do you mean that you don't get a response when you go to
http://localhost:8080/WeighPro/CommPortSample
in a browser?
As Suresh says, you cannot call a Servlet directly from a main method.
Your Servlet should instead call methods on other classes, and those other classes should be callable from the main method, or from Test Cases. You need to architect your application to make that possible.
import java.io.BufferedInputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public class OutBoundSimul {
public static void main(String[] args) {
sendReq();
}
public static void sendReq() {
String urlString = "http://ip:port/applicationname/servletname";
String respXml = text;
URL url = null;
HttpURLConnection urlConnection = null;
OutputStreamWriter out = null;
BufferedInputStream inputStream = null;
try {
System.out.println("URL:"+urlString);
url = new URL(urlString);
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
System.out.println("SendindData");
out = new OutputStreamWriter(urlConnection.getOutputStream());
System.out.println("Out:"+out);
out.write(respXml);
out.flush();
inputStream = new BufferedInputStream(urlConnection.getInputStream());
int character = -1;
StringBuffer sb = new StringBuffer();
while ((character = inputStream.read()) != -1) {
sb.append((char) character);
}
System.out.println("Resp:"+sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Invoking Servlet with query parameters Form Main method
Java IO
public static String accessResource_JAVA_IO(String httpMethod, String targetURL, String urlParameters) {
HttpURLConnection con = null;
BufferedReader responseStream = null;
try {
if (httpMethod.equalsIgnoreCase("GET")) {
URL url = new URL( targetURL+"?"+urlParameters );
responseStream = new BufferedReader(new InputStreamReader( url.openStream() ));
}else if (httpMethod.equalsIgnoreCase("POST")) {
con = (HttpURLConnection) new URL(targetURL).openConnection();
// inform the connection that we will send output and accept input
con.setDoInput(true); con.setDoOutput(true); con.setRequestMethod("POST");
con.setUseCaches(false); // Don't use a cached version of URL connection.
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
con.setRequestProperty("Content-Language", "en-US");
DataOutputStream requestStream = new DataOutputStream ( con.getOutputStream() );
requestStream.writeBytes(urlParameters);
requestStream.close();
responseStream = new BufferedReader(new InputStreamReader( con.getInputStream(), "UTF-8" ));
}
StringBuilder response = new StringBuilder(); // or StringBuffer if not Java 5+
String line;
while((line = responseStream.readLine()) != null) {
response.append(line).append('\r');
}
responseStream.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace(); return null;
} finally {
if(con != null) con.disconnect();
}
}
Apache Commons using commons-~.jar
{httpclient, logging}
public static String accessResource_Appache_commons(String url){
String response_String = null;
HttpClient client = new HttpClient();
GetMethod method = new GetMethod( url );
// PostMethod method = new PostMethod( url );
method.setRequestHeader("Content-type", "text/xml; charset=ISO-8859-1");
method.setQueryString(new NameValuePair[] {
new NameValuePair("param1","value1"),
new NameValuePair("param2","value2")
}); //The pairs are encoded as UTF-8 characters.
try{
int statusCode = client.executeMethod(method);
System.out.println("Status Code = "+statusCode);
//Get data as a String OR BYTE array method.getResponseBody()
response_String = method.getResponseBodyAsString();
method.releaseConnection();
} catch(IOException e) {
e.printStackTrace();
}
return response_String;
}
Apache using httpclient.jar
public static String accessResource_Appache(String url) throws ClientProtocolException, IOException{
try {
CloseableHttpClient httpclient = HttpClients.createDefault();
URIBuilder builder = new URIBuilder( url )
.addParameter("param1", "appache1")
.addParameter("param2", "appache2");
HttpGet method = new HttpGet( builder.build() );
// HttpPost method = new HttpPost( builder.build() );
// Create a custom response handler
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
#Override
public String handleResponse( final HttpResponse response) throws IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
return "";
}
};
return httpclient.execute( method, responseHandler );
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
JERSY using JARS {client, core, server}
public static String accessResource_JERSY( String url ){
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource( url );
ClientResponse response = service.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);
if (response.getStatus() != 200) {
System.out.println("GET request failed >> "+ response.getStatus());
}else{
String str = response.getEntity(String.class);
if(str != null && !str.equalsIgnoreCase("null") && !"".equals(str)){
return str;
}
}
return "";
}
Java Main method
public static void main(String[] args) throws IOException {
String targetURL = "http://localhost:8080/ServletApplication/sample";
String urlParameters = "param1=value11&param2=value12";
String response = "";
// java.awt.Desktop.getDesktop().browse(java.net.URI.create( targetURL+"?"+urlParameters ));
// response = accessResource_JAVA_IO( "POST", targetURL, urlParameters );
// response = accessResource_Appache_commons( targetURL );
// response = accessResource_Appache( targetURL );
response = accessResource_JERSY( targetURL+"?"+urlParameters );
System.out.println("Response:"+response);
}
Simply you cannot do that.
A response and request pair will generated by web container. You cannot generate a response object and send to the browser.
By the way which client/browser you are expecting to get the response ? No idea. Right ?
When container receives a request from client then it generates response object and serves you can access that response in service method.
If you want to see/test the response, you have to request from there.

HttpUrlConnection taking too long, why?

i made a HttpUrlConnection GET in Java. And takes a lot to process, the code makes a GET to a URL that returns a JSON. (Which is not that huge, just a couple of rows) Don't know why is taking like A LOT to process from a jQuery ajax call client-side.
This is the Java code:
#RequestMapping(value = "/getchartdata", method = RequestMethod.GET)
public ResponseEntity<String> graphChartData(ModelMap model, HttpServletRequest request) {
String graphName = request.getParameter("graphName");
String subgroup = request.getParameter("subgroup");
HttpURLConnection connection = null;
try {
String configURL = EsbConfig.getProperty("graph.url", "http://localhost:8081");
URL url = new URL(configURL + "/plot/get?graphName="+ graphName+"&subgroup="+subgroup+"&width=100");
connection = (HttpURLConnection) url.openConnection();
connection.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
StringBuilder responseData = new StringBuilder();
while((line = in.readLine()) != null) {
responseData.append(line);
}
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<String>(responseData.toString(), responseHeaders, HttpStatus.CREATED);
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} finally {
if(null != connection) { connection.disconnect(); }
}
return null;
}
I won't add the ajax call since it's pretty plane and simple, nothing to say about that.
If i access directly with the entire URL, i get the json response in nano seconds. If i make the call from client-side, it takes like 10 seconds to retrieve the info.
Any ideas on what's wrong? or any other HTTP get i could implement?
Thanks.

Categories

Resources