Maven HTTP Failure During Build - java

Been reading StackOverflow for a long time, and though I have seen people get this error, I am lost on how they resolved it. I am getting
an Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false', or 'null') at [Source: <!doctype html>HTTP Status [401] [Unauthorized]h1 ... Status Report Message: Authorization Required. The request has not been applied because it lacks valid authentication credentials for the target resource.
I am getting this particular error when I am executing the following:
Json j = new JsonObject();
json.readTemplateString(rep.toString());
where it's getting the response from:
HttpResponse rep = connector.httpGet(url, "", headers);
The Json portion of the code must be taking in an xml file.

This depends a lot on "where" you are making the call from, and what url you are trying to reach. Depending on the source and destination of the connection, you may be required to provide either authentication credentials or a proxy configuration.
If you're executing this code when connected to a VPN for a company, you'll likely need to set a proxy configuration in order for the connection to work.
On the other hand, the url you're trying to connect to might require basic auth credentials. I have no idea what you're trying to connect to, so it's hard to tell whether that's the case.

Related

REST API - how to deal with post and functional errors

I have a REST service which is a POST to create a user, if the user does not exist, the user is created, and the service returns a 200 with the user in a json format.
Case 1: What if the user exists already, do I return a functionnal exception, so a json containing an error (all of this managed by the error handling of spring boot), and what about the http status code
Some people say to send a 303 or a 409 ... many different answers, and what about the response body in that case?
Case 2: What if in the backend we have let say a rule on the name (like containing a space) which returns an error (space not allowed in a name), same questions, do i have to return a functionnal exception and what about the http status code in this case
Somehow I want the API consumer to know what kind of json structure to handle and i guess the http status code helps for that ?
It all depends on how one interprets the various http status codes and how user friendly do you want your HTTP payload responses to be. Below are few suggestions:
NEW USER CREATED : If its a new user and gets created successfully in the backend then you return http status code 201. This is a technical status code. You can also return a functional status in the response body mentioning "User created"
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
USER ALREADY EXISTS : If the user already exists, you should respond with http status code 200 with a response payload body mentioning a functional status "User already exists"
USER CREATION FAILED : If the new user rules are not satisfied at the backend service and it throws an error then the http status code of 400 can be used and functional status in response payload of "User creation failed, please conform to the user name rules" https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
For an API Consumer to know everything about your API's, you may want to provide a API specification document. You may use open API spec(previously known as swagger) https://swagger.io/specification/
Somehow I want the API consumer to know what kind of json structure to handle and i guess the http status code helps for that ?
Not quite.
The HTTP status code is meta data in the transfer documents over a network domain. It communicates the overall semantics of the response (for instance, is the body of the message a representation of a resource, or a representation of an error? is this response cachable? and so on).
For unsafe requests in particular, cache invalidation is sensitive to "non-error status codes". The difference between 303 (non-error status code) and 409 (error status code) can be significant.
The Content-Type header gives you a mechanism to describe the kind (schema) of the message you are returning (ex: application/problem+json).
The way I think about it: the information for your bespoke consumer belongs in the message-body; we lift data from the message-body to the HTTP metadata so that general-purpose components can take advantage of that information (for example, by invalidating cache entries).
So we would normally start by defining the schema and semantics of the message body, and making sure that we have intelligent ways to communicate all of the things we want the caller to know. In other words, we are defining the documents that we pass to the client, and how to extract information from them.
Information that HTTP components need to know get copied from our bespoke document into the standardized forms (status code, headers).
Where things get complicated: the fact that something is an "error" in your domain, that doesn't necessarily mean that it should also be considered to be an "error" in the transfer of documents over a network domain.
A common case: we are using our API to navigate some work through a process; that process has a happy path, and also some exceptional paths that we normally try to avoid (accounts are overdrawn, items are out of stock, etc).
An HTTP request can move work from the happy path to an exception path and still be a "success" in the transfer of documents domain.
The easiest heuristic I know is to think about previously cached copies of responses by the same target URI. If those responses are still re-usable, then you are probably looking at a 4xx status code. If the responses should be invalidated, then you are probably looking at a 2xx or 3xx status code.

java.net.URISyntaxException: Illegal character in query at index on JMETER

I have an application for which I have recorded Jmeter scripts to conduct load testing. Authorization happens via Azure AD.
I have co-related the auth-related such as access tokens, refresh tokens and id tokens that are generated dynamically and also parameterized them in a request that is responsible for calling the API and which would probably require those tokens to authorize the call to the API.
However, I get an error:-
java.net.URISyntaxException: Illegal character in query at index 98:
at java.base/java.net.URI$Parser.fail(URI.java:2938)
at java.base/java.net.URI$Parser.checkChars(URI.java:3109)
at java.base/java.net.URI$Parser.parseHierarchical(URI.java:3197)
at java.base/java.net.URI$Parser.parse(URI.java:3139)
at java.base/java.net.URI.<init>(URI.java:623)
at java.base/java.net.URL.toURI(URL.java:1063)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:615)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:66)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1281)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1270)
at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:630)
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:558)
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256)
at java.base/java.lang.Thread.run(Thread.java:832)
I am not sure where I am going wrong. I have co-related 3 dynamic tokens which are generated as part of the auth token request.
Screenshots in the below link:-
Regular Expression Extractor
Setting parameters
Error on Jmeter
I faced this issue. What I did wrong, was that I did not put the "$" sign before the parameters in the URL.
How I resolved the issue:
When I got the exception, I counted the characters in the URL till the index (given in the exception) which made me realize that something is wrong with the given index, then I checked the tutorial which I was following, and Hoorah! the issue has been found.
Example Image
I believe these "tokens" should go into the HTTP Header Manager as placing them as request parameters adds them to the request URL.
If your application expects the tokens to be a part of the URL (which is kind of strange) then you either need to tick the URL Encode? boxes or wrap the values which can contain the characters requiring encoding into __urlencode() function

Grails encoded params Post Request

I am trying to complete the Instagram Oauth flow,
I currently have the authorization code which I'm to exchange for the access token. I am to make an x-www-form-urlencoded POST request to this endpoint
"https://api.instagram.com/oauth/access_token?"
This is what I've done so far.
String query = "https://api.instagram.com/oauth/access_token/?client_id=" + clientId +"&client_secret="+ clientSecret+ "&grant_type=authorization_code&redirect_uri="+ redirectUri + "&code=" + code
String response = new URL(query).getText()
A JSON string is expected as response.
Please Keep in mind that I'm a beginner.
I haven't read the Instagram documentation but based on your example code there's a couple of things to keep in mind:
you mentioned that you have to make a POST request, your example makes a GET request
never build a URL with untrusted parameter values. This basically means: always encode parameters, never trust them.
There are dozens of 3rd party HTTP Request libraries that give you flexibility and easier insight into aspects like timeouts and redirects. Java 11 has a built-in HTTP client that might ease this as well. But building on your code provided in your question using basic Java connection primitives this might work:
URL url = new URL("https://api.instagram.com/oauth/access_token/?client_id=${URLEncoder.encode(clientId, 'UTF-8')}&client_secret=${URLEncoder.encode(clientSecret, 'UTF-8')}&grant_type=authorization_code&redirect_uri=${URLEncoder.encode(redirectUri, 'UTF-8')}&code=${URLEncoder.encode(code, 'UTF-8')}")
def jsonString = ((HttpURLConnection) url.openConnection()).with {
setRequestMethod('POST')
setRequestProperty('Accept', 'application/json')
setDoInput(true)
connect()
if (getResponseCode() >= 400)
throw new Exception("Error code = ${getResponseCode()}")
inputStream.text
}
Every URL parameter is encoded so that any non-URL safe characters they contain are made safe, then we tell the connection that it will be a 'POST' and that we expect to get back json as input. inputStream.text is groovy code that takes an inputstream from the connection and reads all of the contents and then closes the stream. Since it is the last line of the with closure it is automatically returned as the value of the closure and assigned to the variable jsonString.

Best practise to write a boolean API in Java Sturts 2 server?

I need to write an API to check if a user name already exists in a database.
I want my server (Struts Action class instance in tomcat server) to return true/false.
Its something like this
checkUserName?userName=john
I want to know what is the standard way to do this?
Shall I return a JSON response with just one boolean value ... seems like a overkill.
Shall I do something like manually setting the HTTP header to 200 or 404 (for true/false), but that seems to violate the actual purpose of using the headers which I believe must only be used to indicate network failures etc.
(Too long for a comment.)
I don't see any reason not to return a standard JSON response with something indicating whether or not the user name exists. That's what APIs do: there's nothing "overkill" about providing a response useful across clients.
To your second point: headers do a lot more than "indicate network problems". A 404 isn't a network problem, it means the requested resource doesn't exist. It is not appropriate in your case, because you're not requesting a resource: the resource is checkUserName, which does exist. If instead your request was /userByName/john a 404 would be appropriate if the user didn't exist. That's not an appropriate request in this case, because you don't want to return the user.
A 401 isn't a network problem, it's an authentication issue. A 302 isn't a network problem, it's a redirect. Etc. Using HTTP response codes is entirely appropriate, if they match your requests.

How can I get the full reason phrase (or the raw response) with jax-rs?

I have an API that is returning a response with the following status line, in certain conditions:
HTTP/1.1 500 Internal Server Error: An error occurred (23000): SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'name'
I am catching the resulting WebApplicationException and then using the following to try and get the reason phrase:
e.getResponse().getStatusInfo().getReasonPhrase()
However, this only returns "Internal Server Error" which is not very helpful. I would like to log the full reason phrase so I can log something more specific, when something goes wrong.
Is there any way to get the full phrase? If not, is there a way to get the raw response from the exception's response object? Then I can at least try and parse it myself.
Edit: Also, I can confirm that the body is empty and no suitable information appears in any other header. I'm checking the raw response with Fiddler.
Edit 2: I am using cxf-rt-frontend-jaxrs 2.7.5
As far as I know, the getReasonPhrase call only returns the phrase as defined by the HTTP response code spec -- it's not actually parsing it out of the status line. It's odd that the application you're calling writes the diagnostic message to the status line and not the response body. Perhaps it's a bug in that application?
EDIT As I thought, the reason phrase is hard-coded in the status enum (not even localizable! Bad Sun!)

Categories

Resources