HTTP Status - 401 Unauthorized - spring

I'm trying to convert from curl to java code with intention to call an API to create a token but I get a 401 response.
Curl code:
curl -X POST \
https://apigw.dev/commercial/oauth/create-token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=dfdfdfdfd&client_secret=dfdfdf&grant_type=client_credentials'
And here my java code:
#RestController
public class TokenController {
#RequestMapping(value = "/getAccessToken", method = RequestMethod.POST)
public ClientCredentialsResourceDetails getAccessToken(ClientCredentialsResourceDetails resource) throws Exception {
resource.setAccessTokenUri(tokenUri);
resource.setClientId(clientId);
resource.setClientSecret(clientSecret);
resource.setGrantType("client_credentials");
resource.setClientAuthenticationScheme(AuthenticationScheme.header);
resource.setScope(Arrays.asList("read", "write"));
System.out.println(resource);
return resource;
}
}
and here the results:
"timestamp": "2020-04-28T14:02:28.381+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/getAccessToken"
}
I really appreciate your suggestion, Thanks in advance.

You're making a POST request with CURL, but your rest controller is configured as GET. I guess you have another endpoint to /getAccessToken with POST method wich requires the token.
Also, by default, every mehod in a #RestController class will consume an application/json and produce an application/json.
If your request is a Content-Type: application/x-www-form-urlencoded, change the consume type of your request to MediaType.APPLICATION_FORM_URLENCODED_VALUE.

Related

Java springboot POST request giving 404

I am trying a POST request in POSTMAN but even though its reaching the tomcat server node, I get following error in my localhost_access.log file
"POST /app/MyService/myControllerMethod HTTP/1.1" 404 1010
My Controller class is something like this :
#Controller("myServicecontroller")
#RequestMapping({"/MyService"})
public class MyServiceController {
#RequestMapping(value = {"myControllerMethod"}, method = {RequestMethod.POST})
public String myControllerMethodBackgroundCallBack(HttpServletRequest httpReq,
#RequestBody String request) {
// rest piece of code
}
}
Now my postman curl I am trying with empty data (tried with some value also) but get above 404 error response
curl --location --request POST 'http://my-ip-address:8080/app/MyService/myControllerMethod' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'My-Header-One: lskdnansdlknalkasndl' \
--header 'My-Header-Two: sadasdsa' \
--data-raw '{}'
What am I doing wrong? (app in above url is my service which works fine in other requests)
Same thing when I try with following code it is able to hit the api 200
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestBody(requestString);
httpClient.setConnectionTimeout(httpReadTimeOut);
httpClient.executeMethod(postMethod);
I have successfully replicated this issue and found the root cause.
Root Cause
#ResponseBody annotation is missing in myControllerMethodBackgroundCallBack method.
Fix
#RequestMapping(value = {"myControllerMethod"}, method = {RequestMethod.POST})
#ResponseBody
public String myControllerMethodBackgroundCallBack(HttpServletRequest httpReq,
#RequestBody String request) {
// rest piece of code
}
}
Why?
#ResponseBody annotation is required with #Controller annotation and if use #RestController annotation then #ResponseBody annotation is not required.
In Short-
#RestController = #Controller + #ResponseBody
You can read more about #Controller and #RestController here https://medium.com/#akshaypawar911/java-spring-framework-controller-vs-restcontroller-3ef2eb360917

Spring ControllerAdvice how to return Json or html page according to Accept request header?

Now, App can return a cutstom 404 page.
#ControllerAdvice
class GlobalControllerExceptionHandler {
#ResponseStatus(HttpStatus.NOT_FOUND)
#ExceptionHandler(NoHandlerFoundException.class)
public String handle404(WebRequest request) {
return "/exceptions/404";
}
}
And I wonder how should I do, if I want to get a JSON when Accept request header is Accept: application/json, like this:
$> curl -H "Accept: application/json" http://localhost:8080/no-such-page
{"timestamp":"2018-04-11T05:56:03.845+0000","status":404,"error":"Not Found","message":"No message available","path":"/no-such-page"}```

how to send a single String to a RestAPI endpoint using CURL

I have a #RestController with an endpoint that receives a single String :
#RestController
public class ScriptController {
private Logger logger = LoggerFactory.getLogger(ScriptController.class);
public ScriptController(Engine engine) {
this.engine = engine;
}
#RequestMapping(value = "/run", method = RequestMethod.POST)
public Object run(#RequestBody String script){
return engine.run(script);
}
}
when I send a request to this endpoint using CURL :
curl --request POST localhost:9999/run --data-binary "testObj.hi()"
I am not receiving the exact String ("testObj.hi()") in the Controller, instead I receive the following one :
testObj.hi%28%29=
what is the problem?
when I change the method from POST to GET (in both sides) it works! but I want to use POST method.
By default, the request body is URL encoded in HTTP requests, and since there is no content-type header, spring boot doesn't decode the encoded characters.
Specifying Content-Type header will solve the problem, something like this:
curl --request POST localhost:8080/run --data-binary "testObj.hi()" -H 'Content-Type: text/utf-8'
It works in case of GET requests because parameters are expected to be URL encoded in case of GET request and they are decoded by the spring.

Parse request parameters without writing wrapper class

How to handle json requests and parse the request parameters in dropWizard?
#POST
#Path("/test")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public String test(#Context final HttpServletRequest request) {
JSONObject data=new JSONObject();
System.out.println(request);
System.out.println(request.getParameterMap());
System.out.println(">>>>>>>>>");
return "{\"status\":\"ok\"}";
}
I wrote the above code and tried the following request.
curl -XPOST -H "Content-Type: application/json" --data {"field1":"val1", "field2":"val2"} http://localhost:8080/test
But request.getParameterMap() is {}
How to parse the parameters without writing a wrapper class?
Your curl command may need some additional quotes around the data (I'm getting an error without them):
curl -H "Content-type: application/json" -X POST -d '{"field1":"tal1", "field2":"val2"}' http://localhost:8080/test
You are sending a POST request without URL parameters. I'm not sure why you are expecting to see something there.
I don't know which version of dropwizard you are using but I couldn't make the combination of #POST and #Path("/something") annotation to behave when a method is annotated. I'm getting HTTP ERROR 404.
To make it work I have to move the #Path annotation to the resource/class level and leave only the #Post annotation at the method.
#Path("/test")
public class SimpleResource {
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String test(final String data) throws IOException {
System.out.println("And now the request body:");
System.out.println(data);
System.out.println(">>>>>>>>>");
return "{\"status\":\"ok\"}";
}
}
To get the body of the request as String just do as above. Taken from here: How to get full REST request body using Jersey?
The console looks like:
INFO [2016-11-24 15:26:29,290] org.eclipse.jetty.server.Server: Started #3539ms
And now the request body:
{"field1":"tal1", "field2":"val2"}
>>>>>>>>>

Unsupported Media Type in jersey RESTfull api

I am trying to build a RESTfull API using the Jersey library but it gives me an exception.
Here is my Docs class
#XmlRootElement
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
public class Docs {
#XmlElement(name = "field")
public String field;
#XmlValue
public String content;
}
#Path("/update")
public class Update {
#POST
#Path("/xml")
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public String createIndexXML(Docs docs)
throws Exception {
System.out.println(docs.content);
return "It works";
}
}
If I try to check it using CURL it throws Error 415 Unsupported Media Type
curl -XPOST "http://localhost:8089/update/xml" -d '<docs>
<field>title</field>
</docs>'
You need to add the content type to your request header. Add -H "Content-Type: application/xml" to yourcurl` call.
I think you're also going to find that there are problems with your annotations on your bean - but that's another issue...
This should work:
curl -H "Content-Type: application/xml"
-X POST -d "<docs><field>title</field></docs>" "http://localhost:8089/update/xml"
You should also try Accept: application/xml; watch out for defining both #Produces and #Consumes! See Using #Consumes and #Produces to Customize Requests and Responses.

Resources