Getting HTTP 406 while calling external site from within servlet - java

I have the following code in my servlet:
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
public void doIt(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
URL url = new URL("http://some.url.that.works.well.nl/q=hello&ie=nl&cx=hdyehgfyegywjehdkwed:7364du7");
URLConnection conn = url.openConnection();
conn.connect();
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream())); // This line is generating the error
String line = "";
PrintWriter pw = response.getWriter();
while((line = br.readLine()) != null) {
pw.println(line);
}
}
running this servlet in tomcat gives me an http 406 error.
What I try to do is from within my servlet call google site search and I would like to parse the receieved (XML) result. (For now I just print te received result).
Trying the url in a browser is giving the correct result.
What am I missing here?
Kind regards,
Werner

A 406 HTTP error means that the server couldn't build a response to your request with an acceptable content type. It means that your URLConnection asks the server for a given content type, and the server can't find an appropriate one.
You can change the content type requested by your URLConnection using the setRequestProperty(String, String) method. You will have to add something like:
conn.setRequestProperty("accept", "text/xml");
(This supposes the server sends XML back to you)

I solved the problem.
I used wireshark to investigate what was send across the wire.
My url contained a space and that was causing all the problems.
As told before I wanted to contact google search and my url looked something like:
http://www.google.com/search?q=golden handpressure&ie=8758438&cx=hjfweufhweufwef:9e
this is working in the browser address bar but not in java.
With wireshark I found out that my request header contained:
Request URI: http://www.google.com/search?q=golden
Request version: handpressure&ie=8758438&cx=hjfweufhweufwef:9e
This is ofcourse not correct. it should all be one field called 'Request URI'.
Changing the space into '%20' solved the problem.

I think it has to do with Accept Headers. Can you check the accept-headers exchanged.

Check the server for Content-Type response header. It should return :
Content-Type:text/xml; charset=UTF-8
charset=UTF-8 should be there in response. If not add it to header if server is in your control.

Related

Setting Response Headers of HTTPServeletResponse

So, I am constructing a URL from values from a database. Now, I want to make sure that the response headers are what I specify for this URL. How do I achieve this?
For instance, if I construct a URL such as www.google.com/username=ak&password=bk, I want to make sure that the connection is keep alive for the response that you get when you hit the URL. How do I do this within JSP/Java?
The reason being, I'm trying to render a video on an iOS device from my CMS however this doesn't work and from what I have read, the response headers must be set. How do I set response headers for a URL that I might hit?
The following method is how I am setting the response however the response is not the url I make. The URL I make is something like www.uisghsfgsgsfg.com/cs/sksjdgs/appl. I am confused as to what the response means in the context of this page.
class URLConstructor extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Connection", "Keep-Alive");
ByteArrayOutputStream byteStream =
new ByteArrayOutputStream(512);
response.setContentLength(byteStream.size());
response.addHeader("Connection", "Keep-Alive");
}
}
Assumption: You have access to the server which transmits the video.
The code which transmits the video to your client (IOS device) should set the response headers before sending the response(video content). If it is a Java program which serves the request for the video, you can set the appropriate header in the Servlet API (See Martin's link).
Hope that helps.

Response/Request between Javascript/Java Servlet

I have a simple test client-server app. Client is html/javascript, server - Java Servlet
First of all I want to test request/response mechanism. Therefore I have used a simple code for cliet(jQuery):
$.get ("http://localhost:8081/TestProject/BasicServlet",
function(data) {
alert('Data:' +data);
}
);
And on the server side:
protected void doGet(HttpServletRequest req, HttpServletResponse res) ... {
String callBack = "TestCallback";
res.setContentType("text/html");
ServletOutputStream out = res.getOutputStream();
out.write(callBack.getBytes("UTF-8"));
out.flush();
}
So, Servlet catches request from client, but I have a problem with response, response header looks good, with character attributes, but I don't receive the callBack data
As response in Firebug I have 3 tabs, Header, Answer, HTML. Answer and HTML are empty
EDIT:
I have found a Problem: it was Access-Control-Allow-Origin violation.
Thanks for help !
As per the documentation in here
http://download.oracle.com/javaee/6/api/javax/servlet/ServletResponse.html#getOutputStream
is used for sending binary data. So my guess is that Content-Type header is set as some MIME type which is not recognized by jQuery. I suggest you check whether the Content-Type header is still "text/html" in the response using FireBug, or use
PrintWriter writer = res.getWriter();
writer.write(callBack);
writer.flush();
By the way, for sending textual data using PrintWriter is the recommended approach.
Try out.print() instead of out .write() you will get the response in your ajax call.

How to drop body of a request after checking headers in Servlet

I want to check the header of the request whether it contains a certain header or not before continuing with the body. For example, I want to check whether a multipart/form-data contains "Authorization" in the header or not. If it is not then there is no need to continue with uploading the multipart body which are generally quite large for file uploading.
Does servlet allow you to do this? I have tried to search on google randomly but there is no luck. Here is the code i try in my servlet but it still continues with recieving the body before this doPost method is called. It seems that the stream is fully received before the servlet is invoked.
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/plain");
if (request.getHeader("Authorization") == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
out.println("Status: " + HttpServletResponse.SC_UNAUTHORIZED + " - UNAUTHORIZED");
return;
}
// ... the rests
}
That's the limitation of HTTP. You can't send a response when the request hasn't been read fully to end.
RFC 2616 says:
An HTTP/1.1 (or later) client sending a message-body SHOULD monitor the network connection for an error status while it is transmitting the request. If the client sees an error status, it SHOULD immediately cease transmitting the body.
So I disagree, this is not a HTTP limitation but a servlet one.

How to make a servlet interact with the API of a website and also store the XML response?

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String text = "some text";
response.setContentType("text/plain"); // Set content type of the response so that jQuery knows what it can expect.
response.setCharacterEncoding("UTF-8"); // You want world domination, huh?
response.getWriter().write(text); // Write response body.
}
If I use this servlet , where request variable will have the url of the API of the website . Then how do I capture the response ? I would want to know what is the code to do that , and is this the right way to go about it when trying to build a JSP page that deals with interacting with an API of a website and showing data ?
You're confusing things. The HttpServletRequest is the HTTP request which the client (the webbrowser) has made to reach the servlet. The HttpServletResponse is the response which you should use to send back the result to the client (the webbrowser).
If you want to fire a HTTP request programmatically, you should use java.net.URLConnection.
URLConnection connection = new URL("http://example.com").openConnection();
InputStream input = connection.getInputStream(); // This contains the response. You need to convert this to String or some bean and then display in JSP.
See also:
How to use java.net.URLConnection to fire and handle HTTP requests

Java http call returning response code: 501

I am having an issue with this error:
**Server returned HTTP response code: 501 for URL: http://dev1:8080/data/xml/01423_01.xml**
See this code:
private static Map sendRequest(String hostName, String serviceName) throws Exception {
Map assets = null;
HttpURLConnection connection = null;
Authenticator.setDefault(new Authenticator());
URL serviceURL = new URL(hostName + "/" + serviceName);
connection = (HttpURLConnection)serviceURL.openConnection();
connection.setRequestMethod("GET");
ClientHttpRequest postRequest = new ClientHttpRequest(connection);
InputStream input = null;
/*
At line input = postRequest.post(); I get the following error
Server returned HTTP response code: 501 for URL: http://dev1:8080/data/xml/01423_01.xml
Yet if I enter that url in my browser it opens up fine.
Is this a common problem? Is there some type of content type I need to set?
*/
input = postRequest.post();
connection.disconnect();
return assets;
}
A 501 response means "not implemented", and is usually taken to mean that the server didn't understand the HTTP method that you used (e.g. get, post, etc).
I don't recognise ClientHttpRequest , but you have a line that says
connection.setRequestMethod("GET");
and then a line that says
input = postRequest.post();
I'm not sure what post() actually does, but does that mean send a POST request? If so, then that contradicts the GET specified in the first line.
Either way, the server is saying that it doesn't under the GET or the POST method, whichever one your code is actually sending. You need to find out what method the server does support for that URL, and use that.
Perhaps you should check your port settings:
new URL(hostName + "/" + serviceName);
Looks like the port number ":8080" is missing.
Some server expect additional information from the client in the request like a user agent or some form data. Even cookies could be expected by the application running on the server. You should also check the complete response and not only the response code.
I would recommend you to use a library like httpclient that is more convenient:
https://hc.apache.org/httpcomponents-client-ga/index.html
Here is simple usage example:
https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java

Categories

Resources