I have method like,
#POST
#Produces(MediaType.APPLICATION_XML)
#Consumes("text/plain")
public File addFile(String filePath){
return fileService.addFile(filePath);
}
And I am using "Postman rest client" for testing the post request and simply type a path like c:\myFile.txt in the raw section
but no String is passed to method, but when I hard-code the path it works
Is the problem from #consume ?
Please see the answer below
#POST
#Produces(MediaType.APPLICATION_XML)
#Consumes(MediaType.TEXT_PLAIN)
public File addFile(String filePath){
return fileService.addFile(filePath);
}
And the header content type
as text/plain while sending the request to server from postman
for your reference please see the image below
As stated above, there is no annotation to fetch the body of the request with Jax-RS ; The original definition of the service is correct.
The problem probably comes from postman settings.
You should select Body > raw > Text (text/plain).
Related
I just want to create a simple REST service and it uses #GET and #POST.
for the #GET function, everything is ok but for #POST, when I want to create a new user on my server the browser just keeps sating (METHOD NOT ALLOWED).
I read so many articles about how to fix this error but I haven't got anything yet.
My code for #POST :
#Path("/hello")
public class HelloResource(){
#POST
#Produces(MediaType.APPLICATION_JSON)
#Path("/post")
public Response createUser(#PathParam("name") String name,#PathParam("address") String address,#PathParam("birthYear") String birth,#PathParam("ps") String password) throws NotAllowedException,MethodNotFoundException,Exception {
DataStore.getInstance().putPerson(new Person(name, address, Integer.parseInt(birth), password));
String json = "{\n";
json += "\"status\": " + '"'+"CREATED" +'"'+ ",\n";
json+="}";
return Response.status(200).entity(json).build();
}}
I also tried adding #Consumes function with (MediaType.APPLICATION.JSON) and (MediaType.TEXT_PLAIN) but nothing changed.
Also the URL I enter for posting is :
http://localhost:8080/HelloREST/rest/hello/post?name=PouYad&address=mustbejsonlater&birthYear=2005&ps=12345
As you see I also tried so many exception handlers.
Can someone please help?
if you enter your URL in the browser URL address field, it won't work because the browser will send a "GET" request. So you must use a client that will allow you to send a "POST" like PostMan. Or write your own small httpConnection function that sends a "POST"
You also have to change the #PathParam to #FormParam for it to work (#QueryParam will also work, but because it is POST, it is best to use #FormParm).
Access URL directly through browser can only create Get Request, not POST Request
You should
Create HTML Form, set the action to your service url with POST method, and then submit it.
Use Rest Client like postman to access your service with POST method.
Write your own Http Client using java.net.http api or just simply use
one of the handy libraries/frameworks (Like Spring has RestTemplate).
The code is as follow.Where I am checking the content type extracted from the header then I want to write the code and return the response from the same method.
#POST
#Produces(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_XML)
public Response addMessage(Message message , #Context UriInfo uriInfo,
#HeaderParam ("content-type") String contentType) throws
URISyntaxException
{
//Conditional check based on the content type.
if(contentType.equals("application/json")) {
return json;
}else {
return xml;
}
}
How a rest API will return both Json and XML response depending on the input header?
First , your usage of multiple #Produces on same method is incorrect. A String[] can be specified for all types that you wish to produce with #Produces , Annotation Type Produces
And for your main question, I agree with vlumi's comment that ,
You should just return the Response built with the object to return,
and let JAX-RS handle the serialization into XML or JSON, depending on
which the client expects/prefers
i.e. let the framework do it for you depending on Accept header as specified by client as Raj has already mentioned in comments,
You have to pass the request header Accept: application/json or
application/xml
Jersey Multiple Produces
I am trying to do a get call with request body(JSON) as the request parameter list exceeds the limit. I am able to send the request via postman/insomnia and request is reaching till controller without any error. But the "requstBody" is empty at controller. What i am missing here?
#GET
#Path("\path")
#Consumes(APPLICATION_JSON)
#Produces(APPLICATION_JSON)
public Response getResponse(String requestBody) throws IOException { }
When I replaced #GET with #POST, requestBody has value. For GET call do we need to add anything more?
I am trying to do a get call with request body(JSON) as the request parameter list exceeds the limit. I am able to send the request via postman/insomnia and request is reaching till controller without any error. But the "requstBody" is empty at controller. What i am missing here?
One thing you are missing is the fact that the semantics of a request body with GET are not well defined.
RFC 7231, Section 4.3.1:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
There are two ways for sending parameters in an Http Get method. PathVariable and RequestParam. In this way, sent parameters are visible in the request URL. for example:
www.sampleAddress.com/countries/{parameter1}/get-time?city=someValues
In the above request, parameter1 is a path variable and parameter2 is a request parameter. So an example of a valid URL would be:
www.sampleAddress.com/countries/Germany/get-time?city=berlin
To access these parameters in a java controller, you need to define a specific name for the parameters. For example the following controller will receive this type of requests:
#GetMapping(value = "/countries/{parameter1}/get-time", produces = "application/json; charset=utf-8")
public String getTimeOfCities(
#PathVariable(value = "parameter1") String country,
#RequestParam(value = "city") String city
){
return "the method is not implemented yet";
}
You are able to send RequestBody through a Get request but it is not recommended according to this link.
yes, you can send a body with GET, and no, it is never useful
to do so.
This elaboration in elasticsearch website is nice too:
The HTTP libraries of certain languages (notably JavaScript) don’t allow GET requests to have a request body. In fact, some users are suprised that GET requests are ever allowed to have a body.
The truth is that RFC 7231—the RFC that deals with HTTP semantics and
content—does not define what should happen to a GET request with a
body! As a result, some HTTP servers allow it, and some—especially
caching proxies—don’t.
If you want to use Post method, you are able to have RequestBody too. In the case you want to send data by a post request, an appropriate controller would be like this:
#PostMapping(value = "/countries/{parameter1}/get-time", produces = "application/json; charset=utf-8")
public String getTimeOfCitiesByPost(
#PathVariable(value = "parameter1") String country,
#RequestParam(value = "city") String city,
#RequestBody Object myCustomObject
){
return "the method is not implemented yet";
}
myCustomObject could have any type of data you defined in your code. Note that in this way, you should send request body as a Json string.
put #RequestBody on String requestBody parameter
#RequestMapping("/path/{requestBody}")
public Response getResponse(#PathVariable String requestBody) throws IOException { }
It could be very simple but it will be very helpful for me to understand...
I used #ResponseBody in my restcontroller to return String value to browser. The response string is successfully received in browser.
ie:
#RequestMapping(value="/foo", method=RequestMethod.GET)
#ResponseBody
public String foo() {
return "bar";
}
What is the content-type of above response? If this is going to be like writing setAttribute in servlet response what could the attribute name?
If the browser accept only "application/json" how spring will treat the response?
Submitted code produces text/html, as do all mapped Controller methods by default. If you want to produce application/json, you have to change your RequestMapping to
#RequestMapping(value="/foo", method=RequestMethod.GET, produces = "application/json")
However this is not a valid Json String, you would have to change it because the method you submitted would return empty body. The submitted example would be valid text/plain.
When the request contains header "Accept: application/json" and other content type is returned, Spring returns Json-type response explaining that HttpMediaTypeNotAcceptableException was thrown.
Regarding the servlet analogy - please explain, I don't fully understand what you mean. The String is returned as response body, it's very different from request attributes. What would you like to achieve?
I assume the content type will be plain/text. If the request sets accept to "application/json" it depends on your browser/tool. Most rest clients won't display it as it is not application/json. If you invoke the API directly I would assume it is displayed due to browser content sniffing (can be disabled via a header).
I'm using Jersey to create REST API. I have one POST method and as a response from that method, the user should be redirected to a custom URL like http://example.com that doesn't have to be related to API.
I was looking at other similar questions on this topic here but didn't find anything that I could use.
I'd suggest altering the signature of the JAX-RS-annotated method to return a javax.ws.rs.core.Response object. Depending on whether you intend the redirection to be permanent or temporary (i.e. whether the client should update its internal references to reflect the new address or not), the method should build and return a Response corresponding to an HTTP-301 (permanent redirect) or HTTP-302 (temporary redirect) status code.
Here's a description in the Jersey documentation regarding how to return custom HTTP responses: https://jersey.java.net/documentation/latest/representations.html#d0e5151. I haven't tested the following snippet, but I'd imagine that the code would look something like this, for HTTP-301:
#POST
public Response yourAPIMethod() {
URI targetURIForRedirection = ...;
return Response.seeOther(targetURIForRedirection).build();
}
...or this, for HTTP-302:
#POST
public Response yourAPIMethod() {
URI targetURIForRedirection = ...;
return Response.temporaryRedirect(targetURIForRedirection).build();
}
This worked for Me
#GET
#Path("/external-redirect2")
#Consumes(MediaType.APPLICATION_JSON)
public Response method2() throws URISyntaxException {
URI externalUri = new URI("https://in.yahoo.com/?p=us");
return Response.seeOther(externalUri).build();
}