Servlet communticating with another server [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
communication between remote servlets
Is it possible to send objects between servlets on different servers?
The issue is, when my servlet receives a http request, before sending a response, it would need to send some data to another web application (on different server), get a response, and then process the received data. However I don't really know how to tackle the problem. Is it possible for a servlet to send a http request to another servlet, and then get the response from it?

Of course it is possible - you can create an HttpURLConnection in it in the same way you would do it from JavaSE. Usually what I do is, in case of an error, to forward to the client the original (second server) HTTP error code.

Here's an example of how to use HttpURLConnection to communicate with another servlet (or any http server)...
URL url = new URL ("http://host/myservlet");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput (true);
connection.setDoInput (true);
OutputStream os = connection.getOutputStream();
//TODO: optionally, send something through the OutputStream to your servlet
os.flush();
os.close();
InputStream is = connection.getInputStream();
//TODO: retrieve your results from the InputStream
is.close();
Be sure to close your streams when done or use try-with-resources blocks. You can use ObjectInputStream or InputStreamReader based on your needs. You can also use the setRequestProperty method of the HttpURLConnection to define things such as the user-agent or cookies if needed.

Related

How to send special character via HTTP post request made in Java

I need to send data to another system in a Java aplication via HTTP POST method. Using the Apache HttpClient library is not an option.
I create a URL, httpconection without problems. But when sending special character like Spanish Ñ, the system complains it is receiving
Ñ instead of Ñ.
I've read many post, but I don't understand some things:
When doing a POST connection, and writing to the connection object, is it mandatory to do the URLEncode.encode(data,encoding) to the data being sent?
When sending the data, in some examples I have seen they use the
conn.writeBytes(strData), and in other I have seen conn.write(strData.getBytes(encoding)). Which one is it better? Is it related of using the encode?
Update:
The current code:
URL url = new URL(URLstr);
conn1 = (HttpsURLConnection) url.openConnection();
conn1.setRequestMethod("POST");
conn1.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(conn1.getOutputStream());
wr.writeBytes(strToSend);//data sent
wr.flush();
wr.close();
(later I get the response)
strToSend has been previously URLENCODE.encode(,"UTF-8")
I still don't know if I must use urlencode in my code and/or setRequestProperty("Contentype","application/x-www-formurlencode");
Or if I must use .write(strToSend.getByte(??)
Any ideas are welcome. I am testing also the real server (I dont know very much about it)

How to re-use socket connections? [duplicate]

This question already has answers here:
Persistent HttpURLConnection in Java
(3 answers)
Closed 9 years ago.
I am interested in reusing an HttpUrlConnection (as part of a statefull protocol between server and client that I'm developing).
I know that there is an Connection=keep-alive header for persistent http.
Now, I want to know how to reuse such a conenction.
I have written this code:
URL u = new java.net.URL("http://localhost:8080/Abc/Def");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Connection", "keep-alive");
c.setHeader("A","B");
c.getInputStream() //here I see that server gets my messages (using DEBUG)
c.setHeader("B","C"); //
Now how do I resend this "B" header to the server, I tried re-connect etc,but nothing gets it to work.
And the server also perform response.setHeader("Connection", "keep-alive");
I've looked in many forums, but no one wrote about this. Maybe HttpURLConnection doesn't handle this?
You don't. You close this one and create a new one. It does TCP connection pooling and keepalive behind the scenes.

How to Reuse HttpUrlConnection? [duplicate]

This question already has answers here:
Persistent HttpURLConnection in Java
(3 answers)
Closed 9 years ago.
I am interested in reusing an HttpUrlConnection (as part of a statefull protocol between server and client that I'm developing).
I know that there is an Connection=keep-alive header for persistent http.
Now, I want to know how to reuse such a conenction.
I have written this code:
URL u = new java.net.URL("http://localhost:8080/Abc/Def");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Connection", "keep-alive");
c.setHeader("A","B");
c.getInputStream() //here I see that server gets my messages (using DEBUG)
c.setHeader("B","C"); //
Now how do I resend this "B" header to the server, I tried re-connect etc,but nothing gets it to work.
And the server also perform response.setHeader("Connection", "keep-alive");
I've looked in many forums, but no one wrote about this. Maybe HttpURLConnection doesn't handle this?
You don't. You close this one and create a new one. It does TCP connection pooling and keepalive behind the scenes.

Reading from a URLConnection

I have a php page in my server that accepts a couple of POST requests and process them. Lets say it's a simple page and the output is simply an echoed statement. With the URLConnection I established from a Java program to send the POST request, I tried to get the input using the input stream got through connection.getInputStream(). But All I get is the source of the page(the whole php script) and not the output it produces. We shall avoid socket connections here. Can this be done with Url connection or HttpRequest? How?
class htttp{
public static void main(String a[]) throws IOException{
URL url=new URL("http://localhost/test.php");
URLConnection conn = url.openConnection();
//((HttpURLConnection) conn).setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write("Hello");
wr.flush();
wr.close();
InputStream ins = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader in = new BufferedReader(isr);
String inputLine;
String result = "";
while( (inputLine = in.readLine()) != null )
result += inputLine;
System.out.print(result);
}
}
I get the whole source of the webpage test.php in result. But I want only the output of the php script.
The reason you get the PHP source itself, rather than the output it should be rendering, is that your local HTTP server - receiving your request targeted at http://localhost/test.php - decided to serve back the PHP source, rather than forward the HTTP request to a PHP processor to render the output.
Why this happens? that has to do with your HTTP server's configuration; there might be a few reasons for that. For starters, you should validate your HTTP server's configuration.
Which HTTP server are you using on your machine?
What happens when you browse http://localhost/test.php through your browser?
The problem here is not the Java code - the problem lies with the web server. You need to investigate why your webserver is not executing your PHP script but sending it back raw. You can begin by testing using a simple PHP scipt which returns a fixed result and is accessed using a GET request (from a web browser). Once that is working you can test using the one that responds to POST requests.

RequestDispatcher for remote server?

I am trying to create a HttpServlet that forwards all incoming requests as is, to another serlvet running on a different domain.
How can this be accomplished? The RequestDispatcher's forward() only operates on the same server.
Edit: I can't introduce any dependencies.
You can't when it doesn't run in the same ServletContext or same/clustered webserver wherein the webapps are configured to share the ServletContext (in case of Tomcat, check crossContext option).
You have to send a redirect by HttpServletResponse.sendRedirect(). If your actual concern is reusing the query parameters on the new URL, just resend them along.
response.sendRedirect(newURL + "?" + request.getQueryString());
Or when it's a POST, send a HTTP 307 redirect, the client will reapply the same POST query parameters on the new URL.
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
response.setHeader("Location", newURL);
Update as per the comments, that's apparently not an option as well since you want to hide the URL. In that case, you have to let the servlet play for proxy. You can do this with a HTTP client, e.g. the Java SE provided java.net.URLConnection (mini tutorial here) or the more convenienced Apache Commons HttpClient.
If it's GET, just do:
InputStream input = new URL(newURL + "?" + request.getQueryString()).openStream();
OutputStream output = response.getOutputStream();
// Copy.
Or if it's POST:
URLConnection connection = new URL(newURL).openConnection();
connection.setDoOutput(true);
// Set and/or copy request headers here based on current request?
InputStream input1 = request.getInputStream();
OutputStream output1 = connection.getOutputStream();
// Copy.
InputStream input2 = connection.getInputStream();
OutputStream output2 = response.getOutputStream();
// Copy.
Note that you possibly need to capture/replace/update the relative links in the HTML response, if any. Jsoup may be extremely helpful in this.
As others have pointed out, what you want is a proxy. Your options:
Find an open-source Java library that does this. There are a few out there, but I haven't used any of them, so I can't recommend any.
Write it yourself. Shouldn't be too hard, just remember to deal with stuff like passing along all headers and response codes.
Use the proxy module in Apache 2.2. This is the one I'd pick, because I already know that it works reliably.
Jetty has a sample ProxyServlet implementation that uses URL.openConnection() under the hood. Feel free to use as-is or to use as inspiration for your own implementation. ;-)
Or you can use Apache HttpClient, see the tutorial.

Categories

Resources