Unable to connect to omniture rest API 1.4 - java

We are trying to connect to omniture rest API 1.4 using Java for report.Get. We are unable to create connection. The user id and password are working fine on UI but while making HTTP connection we are getting 400 bad request. Same code works fine with rest API 1.3 for company.reportSuites method. Code if failing while creating input stream. We did checked HTTP response code for connection at it is also coming 400.
public class OMTR_REST {
private static String USERNAME = "XXXXXXX";
private static String PASSWORD = "xXXXXXXXX";
private static String ENDPOINT = "https://api.omniture.com/admin/1.4/rest/"; //san jose endpoint, change for your company's datacenter
private OMTR_REST() {}
public static String callMethod(String method, String data) throws IOException {
URL url = new URL(ENDPOINT + "?method=" + method);
URLConnection connection = url.openConnection();
connection.addRequestProperty("X-WSSE", getHeader());
connection.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(data);
wr.flush();
InputStream in = connection.getInputStream();
BufferedReader res = new BufferedReader(new InputStreamReader(in, "UTF-8"));
StringBuffer sBuffer = new StringBuffer();
String inputLine;
while ((inputLine = res.readLine()) != null)
sBuffer.append(inputLine);
res.close();
return sBuffer.toString();

There was a change in the API from version 1.3 to 1.4. The Get method now returns a status of 400 if the report in not ready. To me, it was a bad choice to return a HTTP 400 error (Bad request) when the report in not ready but that is what they are doing. See page 13 in the document below.
https://github.com/AdobeDocs/analytics-1.4-apis

I see few mistakes in your sample:
you should not use api.omniture.com for every request. First request should call api.omniture.com using Company.GetEndpoint method in order to get the correct endpoint, then use it for next requests.
when a wrong endpoint is used you could receive an HTTP 301 response. I'm not sure your implementation handle this case.
when you receive a HTTP 400 error (bad request). Well, that's exactly what has happened, in your example you're JSON writing directly into the body and many things could go wrong. Wrong type for a value, wrong upper/lower case for a key. Using a JAX-RS or another REST client should make your life simpler.
I have built a working Omniture REST API sample with JAX-RS where the model is clear easy to debug/modify.
Update
Recently I have found this:
https://github.com/Adobe-Marketing-Cloud/analytics-java-library

Related

How to work with server response codes in java?

I am new to programming (especially in java) and I most likely lack knowledge with server work in java, my question is that I could send a request to the server and at the same time receive a response in the form of a response code, for example 404 (file not found), please someone tell me how to correctly implement this
the code we currently have
public static void Connection(int portNumber, String addr, String request) throws UnknownHostException, IOException {
URL url = new URL(addr);
String postData = request; // html request
int response = 0;
responses = response;
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(postData.length()));
//<-------------------------------------Add a response code------------------------------------->//
try (DataOutputStream dos = new DataOutputStream(conn.getOutputStream())) {
dos.writeBytes(postData);
}
try (BufferedReader bf = new BufferedReader(new InputStreamReader(
conn.getInputStream())))
{
String line;
while ((line = bf.readLine()) != null) {
System.out.println(line);
}
}
}
Honestly. I've been scouring the internet and trying to find this in java books, but I haven't been able to find a proper answer
If you just want to send Http request and receive the data back you can just use 3d party Http clients. The most popular are Apache Http Client with good tutorial - Apache HttpClient Tutorial and OK Http client with good tutorial - A Guide to OkHttp. However, If you want to learn how to use Java classes such as URLConnection so you can write your own code than I can offer you to look at source code of my own Http client that I wrote using those classes. This HttpClient can also be used as 3d party Http client (although it is a simplistic and not well-known as the 3d party clients I mentioned above), but also you can look at the source code that is not that big and (I hope) is well and clearly written. So it could be used as tutorial as well. This HttpClient comes as part of MgntUtils Open Source library written and maintained by me. Here is the source code of HttpClient. Here is its Javadoc. If you want the source code of the whole library you can get it on Github here, and just the library as Maven artifact is available from Maven Central here

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.

Getting "java.net.ProtocolException: Server redirected too many times" Error

I'm making a simple URL request with code like this:
URL url = new URL(webpage);
URLConnection urlConnection = url.openConnection();
InputStream is = urlConnection.getInputStream();
But on that last line, I'm getting the "redirected too many times error". If my "webpage" var is, say, google.com then it works fine, but when I try to use my servlet's URL then it fails. It seems I can adjust the number of times it follows the redirects (default is 20) with this:
System.setProperty("http.maxRedirects", "100");
But when I crank it up to, say, 100 it definitely takes longer to throw the error so I know it is trying. However, the URL to my servlet works fine in (any) browser and using the "persist" option in firebug it seems to only be redirecting once.
A bit more info on my servlet ... it is running in tomcat and fronted by apache using 'mod-proxy-ajp'. Also of note, it is using form authentication so any URL you enter should redirect you to the login page. As I said, this works correctly in all browsers, but for some reason the redirect isn't working with the URLConnection in Java 6.
Thanks for reading ... ideas?
It's apparently redirecting in an infinite loop because you don't maintain the user session. The session is usually backed by a cookie. You need to create a CookieManager before you use URLConnection.
// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...
connection = new URL(url).openConnection();
// ...
connection = new URL(url).openConnection();
// ...
See also:
Using java.net.URLConnection to fire and handle HTTP requests
Duse, I have add this lines:
java.net.CookieManager cm = new java.net.CookieManager();
java.net.CookieHandler.setDefault(cm);
See this example:
java.net.CookieManager cm = new java.net.CookieManager();
java.net.CookieHandler.setDefault(cm);
String buf="";
dk = new DAKABrowser(input.getText());
try {
URL url = new URL(dk.toURL(input.getText()));
DataInputStream dis = new DataInputStream(url.openStream());
String inputLine;
while ((inputLine = dis.readLine()) != null) {
buf+=inputLine;
output.append(inputLine+"\n");
}
dis.close();
}
catch (MalformedURLException me) {
System.out.println("MalformedURLException: " + me);
}
catch (IOException ioe) {
System.out.println("IOException: " + ioe);
}
titulo.setText(dk.getTitle(buf));
I was using Jenkins on Tomcat6 on a unix environment and got this bug. For some reason, upgrading to Java7 solved it. I'd be interested to know exactly why that fixed it.
I had faced the same problem and it took considerable amount of time to understand the problem.
So to summarize the problem was in mismatch of headers.
Consider below being my Resource
#GET
#Path("booksMasterData")
#Produces(Array(core.MediaType.APPLICATION_JSON))
def booksMasterData(#QueryParam("stockStatus") stockStatus : String): Response = {
// some logic here to get the books and send it back
}
And here is client code, which was trying to connect to my above resource
ClientResponse clientResponse = restClient.resource("http://localhost:8080/booksService").path("rest").path("catalogue").path("booksMasterData").accept("application/boks-master-data+json").get(ClientResponse.class);
And the error was coming on exactly above line.
What was the problem?
My Resource was using
"application/json"
in
#Produces annotation
and my client was using
accept("application/boks-master-data+json")
and this was the problem.
It took me long to find out this as the error was no where related. Break through was when I tried to access my resource in postman with
Accept-> "application/json" header
it worked fine, however with
Accept-> "application/boks-master-data+json" header
it doesnt.
And again, even Postman was not giving me proper error. The error was too generic. Please see the below image for reference.

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

Connect to site through https

I have some application that should connect to https Site, and receive some.
With connection all is ok, but when i what getInputStream() comes Exception:
java.io.IOException: Server returned HTTP response code: 403 for URL:
Here is the part of code:
String query = siteURL.toExternalForm();
URL queryURL = new URL(query);
String data = "username="+login+"&password="+password;
URLConnection connection = queryURL.openConnection();
connection.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(connection
.getOutputStream());
writer.write(data);
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
Looks like you're not allowed to do what you're trying to do, you're getting an HTTP 403: Forbidden.
Can you open the same URL in your browser?
I think the site have a custom authentication mechanism, in wich you have to supply our username and password as GET parameters. So your url should look like this:
URL url = new URL("http://somesite.org/page?username=<username>&password=password");
... = url.openConnection();
...
If you use url.openConnection, a HTTP GET request is done. If you want to send data with a request, you must use a HTTP POST request. In this case, you can use a third party library, like Apache Commons HttpClient.
BTW: why are u creating a new URL object, if you already have one?

Categories

Resources