#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#Path("/categories")
public Response getAllCategories(#QueryParam(value = "code") String country_code) {
return userService.getAllCategories(country_code);
}
my url:"/user/categories?code=+91"
how can i extracting request parameters "+91" in RESTful web service.
#QueryParam is JAX-RS. If you want to use Spring, the appropriate annotation would be #RequestParam:
public Response getAllCategories(#RequestParam("code") String country_code) {
...
}
But of course, #Path, etc. are also not Spring, so perhaps you should ask yourself if you actually want to use Spring...
Related
Use Case
I have following rest client
#RegisterRestClient(configKey = "service")
public interface Service {
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Response request(#QueryParam("instance") String instance, #BeanParam Input input);
}
Input is a class which is a POJO including properties like
public class Input {
#FormParam("title")
public String title;
#FormParam("description")
public String description;
Problem
The request to the API is working fine, but in my case, the order of properties does matter (The reason behind that is something, I cannot answer at the moment, sorry).
So sending title=Test&description=Testdescription is different to description=Testdescription&title=Test.
Other solutions I have tried
With Form instead of POJO: No data is send to the server
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
CustomResponse requestForm(#QueryParam("instance") String instance, #BeanParam Form form);
With Entit<Form>: No data is send to the server
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
CustomResponse requestForm(#QueryParam("instance") String instance, #BeanParam Entity<Form> form);
Assumption
I found out, that org.jboss.resteasy.client.jaxrs.internal.proxy.processors.FormProcessor is using a HashMap internally. I think that is exactly the problem, because there is no guaranteed order. Is my assumption correct?
Question
How can I work around that and always provide the same order for the API using the Microprofile Rest Client.
Workaround
It works with a org.jboss.resteasy.client.jaxrs.ResteasyClient invoking like
Response response = target
.request(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_FORM_URLENCODED)
.post(Entity.form(form));
It's works for me, see:
#POST
#Path(value = "/auth/realms/{realm}")
#Consumes(APPLICATION_FORM_URLENCODED_VALUE)
AuthenticateResponse authenticate(#PathParam("realm") String realm, MultivaluedMap<String,?> params);
Try to use MultivaluedMap
I am very new to Spring. I have a REST api written in Spring, but I don't know how to return a JSON response with a custom http response code.
I return a JSON response as follows:
public String getUser(String id){
...
return jsonObj;
}
But it always displays 200 http ok status code.
Here are my questions:
How can I synchronize the response JSON and HTTP code?
How is it possible to return JSON response and custom HTTP code in void function?
Use #ResponseStatus annotation:
#GetMapping
#ResponseStatus(HttpStatus.ACCEPTED)
public String getUser(String id) {...}
Alternative way: If you want to decide programmatically what status to return you can use ResponseEntity. Change return type of a method to ResponseEntity<String> and you'll be offered with a DSL like this:
ResponseEntity
.status(NOT_FOUND)
.contentType(TEXT_PLAIN)
.body("some body");
How I do it
Here is how I do JSON returns from a Spring Handler method.
My techniques are somewhat out-of-date,
but are still reasonable.
Configure Jackson
Add the following to the spring configuration xml file:
<bean name="jsonView"
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
</bean>
With that,
Spring will convert return values to JSON and place them in the body of the response.
Create a utility method to build the ResponseEntity
Odds are good that you will have multiple handler methods.
Instead of boilerplate code,
create a method to do the standard work.
ResponseEntity is a Spring class.
protected ResponseEntity<ResponseJson> buildResponse(
final ResponseJson jsonResponseBody,
final HttpStatus httpStatus)
{
final ResponseEntity<ResponseJson> returnValue;
if ((jsonResponseBody != null) &&
(httpStatus != null))
{
returnValue = new ResponseEntity<>(
jsonResponseBody,
httpStatus);
}
return returnValue;
}
Annotate the handler method
#RequestMapping(value = "/webServiceUri", method = RequestMethod.POST)
you can also use the #PostMethod annotation
#PostMethod("/webServiceUri")
Return ResponseEntity from the handler method
Call the utility method to build the ResponseEntity
public ResponseEntity<ResponseJson> handlerMethod(
... params)
{
... stuff
return buildResponse(json, httpStatus);
}
Annotate the handler parameters
Jackson will convert from json to the parameter type when you use the #RequestBody annotation.
public ResponseEntity<ResponseJson> handlerMethod(
final WebRequest webRequest,
#RequestBody final InputJson inputJson)
{
... stuff
}
A different story
You can use the #JsonView annotation.
Check out the Spring Reference for details about this.
Browse to the ref page and search for #JsonView.
Let's say I have:
#GET
public UserList fetch(#PathParam("user") String userId) {
// Do stuff here
}
Now, let's say I have my own type for userId, let's call it UserId. Is it possible to parse that String to UserId when it is passed into the fetch method, i.e.:
#GET
public UserList fetch(#PathParam("user") UserId userId) {
// Do stuff here
}
I realize I can parse the String once I am inside the method, but it would be more convenient that my method gets the type I want.
Well you've attempted to make a GET call with a request body is what I find not very helpful. Do read Paul's answer here -
you can send a body with GET, and no, it is never useful to do so
What would be good to practice is, to make a PUT or a POST call (PUT vs POST in REST) as follows -
#POST
#Path("/some-path/{some-query-param}")
public Response getDocuments(#ApiParam("user") UserId userId,
#PathParam("some-query-param") String queryParam) {
UserId userIdInstance = userId; // you can use the request body further
Note - The ApiParam annotation used is imported from the com.wordnik.swagger.annotations package. You can similarily use FormParam,QueryParam according to your source of input.
Dropwizard is using Jersey for HTTP<->Java POJO marshalling. You could use the various annotations from Jersey #*Param (#FormParam, #QueryParam, etc.) for some of the parameters.
If you need to use map/marshall to/from Java POJOs take a look at the test cases in Dropwizard:
#Path("/valid/")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class ValidatingResource {
#POST
#Path("foo")
#Valid
public ValidRepresentation blah(#NotNull #Valid ValidRepresentation representation, #QueryParam("somethingelse") String xer) {
return new ValidRepresentation();
}
This defines an API endpoint responding to HTTP POST method which expects ValidRepresentation object and "somethingelse" as HTTP method query parameter. The endpoint WILL respond ONLY when supplied with JSON parameters and will return only JSON objects (#Produces and #Consumes on the class level). The #NotNull requires that object to be mandatory for the call to succeed and #Valid instructs Dropwizard to call Hibernate validator to validate the object before calling the endpoint.
The ValidRepresentation class is here:
package io.dropwizard.jersey.validation;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;
public class ValidRepresentation {
#NotEmpty
private String name;
#JsonProperty
public String getName() {
return name;
}
#JsonProperty
public void setName(String name) {
this.name = name;
}
}
The POJO is using Jackson annotations to define how JSON representation of this object should look like. #NotEmtpy is annotation from Hibernate validator.
Dropwizard, Jersey and Jackson take care of the details. So for the basic stuff this is all that you need.
I would like to have two GET methods on my Rest resource class.
one would react if query param has value1 and second on value2
Lets say:
#Path("/myApi")
public class MyApiService {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response methodOne(...) {
...
return ...;
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response methodTwo(...) {
...
return ...;
}
How to achieve conditional routing for query params
I would like to methodOne() reacts if QueryParam is ?type=one and methodTwo() if QueryParam is ?type=two
Choosing servlet handlers based on QueryParam is not a good aproach, and by default no library gives you oportunity to do so.
The closest that comes to mind is PathParam, that is something like Path("\api\{param1}\{param2}") but it's not what you are looking for.
To achieve want your want just
unregister those methods as servlet handlers (Optional, if you don't need them outside of queryparam selection scope)
define a new one that will choose based on query param
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response methodThree(QueryParam('type') String type) {
return type.equals("type1") ? this.methodOne() : this.methodTwo();
}
You cannot have two methods with identical parameters for the same path.
It's not pretty, but it will work..
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response myMethod(#QueryParam("type") String type){
if(type.equals("one"))
return methodOne();
else
return methodTwo();
}
I am trying to return an object as XML in spring, exactly like this guide: http://spring.io/guides/gs/rest-service/
Except that I want the object to return as xml instead of JSON.
Anyone know how I can do that?
Does Spring have any dependancies that can do this as easily for XML? Or, do I need to use a marshaller and then return the xml file some other way?
Spring supports JSON by default, but to support XML as well, do these steps -
In the class you plan to return as response, add xml annotations. for e.g.
#XmlRootElement(name = "response")
#XmlAccessorType(XmlAccessType.FIELD) => this is important, don't miss it.
public class Response {
#XmlElement
private Long status;
#XmlElement
private String error;
public Long getStatus() {
return status;
}
public void setStatus(Long status) {
this.status = status;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
Add produces and consumes to your #RequestMapping on the restful method like below, this helps in making sure what kind of responses and request you support, if you only want response as xml, only put produces = "application/xml".
#RequestMapping(value = "/api", method = RequestMethod.POST, consumes = {"application/xml", "application/json"}, produces = {"application/xml", "application/json"})
public
Then, make sure you return the response object from your method call like below, you can add #ResponseBody just before return type but in my experience, my app worked fine without it.
public Response produceMessage(#PathVariable String topic, #RequestBody String message) {
return new Response();
}
Now, if you are supporting multiple produces types, then based on what client sent as the Accept in the HTTP request header, the spring restful service will return that type of response. If you only want to support xml, then only produce 'application/xml' and the response will always be xml.
If you use JAXB annotations in your bean to define #XmlRootElement and #XmlElement then it should marshall it xml. Spring will marshall the bean to xml when it sees:
Object annotated with JAXB
JAXB library existed in classpath
“mvc:annotation-driven” is enabled
Return method annotated with #ResponseBody
Follow this sample to know more:
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-xml-example/