How to set get query parameter name in spring #RestController Servlet? - java

I have a simple #RestController and want to create a request object that holds any values from a GET query.
Moreover I'd like to use variable names being different from the get query parameter names.
#RestController
public class MyServlet {
#RequestMapping(value = "/start")
public String start(#Valid MyRequest req) {
Logger.log("IN");
return req.getTest();
}
}
public class MyRequest {
#XmlElement(name = "asd")
private String test;
//getter, setter
}
Request: localhost:8080/start?asd=imhere
Result: I'm seing the log statement IN, so the servlet works.
BUT req Parameter is null. Why?
It works if I send the following url: localhost:8080/start?test=imhere
So the servlet works, but not the parameter renaming.

Spring will try to build your MyRequest object using setters or reflecting into private variables, therefore the test variable will only be populated when you send a test parameter.
From the documentation (#RequestMapping - Supported method argument types):
Command or form objects to bind request parameters to bean properties
(via setters) or directly to fields...
Edit - If you want to change names you'll likely need a Converter. See:
docs
mvc example

Related

Java method Overloading with REST - org.codehaus.jackson.map.JsonMappingException

I have a REST service that has a POST endpoint. This POST endpoint needs to receive an object (TravelRequisitionFormDTO) as part of its body:
#POST
#Path("/request")
#ApiOperation(value="Request a trip. Submit the trip request.")
#ApiResponses({
#ApiResponse(code=200, message="Success"),
#ApiResponse(code=404, message="Not Found")
})
#Produces({ MediaType.APPLICATION_JSON })
public Response getSubmitTrip(#HeaderParam("Authorization") String token, #ApiParam(required = true) TravelRequisitionFormDTO travelRequisitionFormDTO, #Context HttpServletRequest request) {
...
}
So when I call the endpoint, I get the following error:
<p><b>message</b> <u>org.codehaus.jackson.map.JsonMappingException: Conflicting setter definitions for property
"contactMethods": utility.dataobjects.ContactObject#setContactMethods(1 params) vs
utility.dataobjects.ContactObject#setContactMethods(1 params)</u></p>
<p><b>description</b> <u>The request sent by the client was syntactically incorrect
(org.codehaus.jackson.map.JsonMappingException: Conflicting setter definitions for property
"contactMethods": utility.dataobjects.ContactObject#setContactMethods(1 params) vs
utility.dataobjects.ContactObject#setContactMethods(1 params)).</u></p>
The reason for the error is because the TravelRequisitionFormDTO has a member variable (called ContactObject) that has two methods that are overloaded. So when it tries to convert the JSON body to JAVA, I guess it does not know which overloaded method to use. I think it sees it as ambiguous.
public void setContactMethods(ArrayList list)
and
public void setContactMethods(String[] list)
I don't want to change ContactObject if possible, because it is used in a number of other places.
Question
Is there any way I can resolve this? i.e. so that the JSON body can be converted successfuly into the Java object?
you can keep single property accepting List. and your Contractobject can consume both Array & List.
You could annotate one setter with Jackson #JsonSetter annotation:
#JsonSetter
public void setContactMethods(ArrayList list)
Make sure that you use right package. In your case it would be org.codehaus.jackson.annotate.JsonSetter like you can see in the error message. It might happen that you have also com.fasterxml.jackson.annotation.JsonSetter in the classpath so you have to be careful not to mix it.
Alternatively you can use #JsonProperty instead.

How can I use an optional number of parameters in a Jersey REST method?

I'm new to Jersey. So, please pardon any mistake.
I'm trying to setup a simple REST ws.
There is a method name getConnectedMHubs that have one required parameter thingID and two optional parameters: time and delta.
Is it possible to use the same method name for the two type of calls, with and without the optional parameters?
I tried to specify two pathes but got a ModelValidationException, that says:
A resource model has ambiguous (sub-)resource method for HTTP method
GET and input mime-types as defined by"#Consumes" and "#Produces"
annotations at Java methods public ...
Code sample:
#Path("/api")
public class RendezvousWebService {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("connectedmhubs/{mhubid}")
public String getConnectedThings(#PathParam("mhubid") String strMHubID) {
// ...
return "{}";
}
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("connectedmhubs/{mhubid}/{time}/{delta}")
public String getConnectedThingsExtended(#PathParam("mhubid") String strMHubID, #PathParam("time") long timestamp, #PathParam("delta") long delta){
// ...
return "{}";
}
}
Using the #Path makes the params mandatory. You can get around this with regular expressions or you can use #QueryParam with #DefaultValue to roll the two methods into one.
Using a path pattern like this:
#Path("connectedmhubs/{mhubid}")
makes the path parameter mandatory. However, you can make use of regular expressions to overcome this limitation. See this link for details.

How to access json Post method values in netbeans using Java

I'm struggling with my restful webservice (Java & Netbeans 8.2)
My method looks like:
#POST
#Path("/usedPacking")
#Consumes(MediaType.APPLICATION_JSON)
public void setUsedPackage( ??? ) {
???
}
Actually I would like to receive a json-message as post-data like:
{"PackageID":"12345","Used":"false"}
My question is:
What do I have to replace the "???" with?
For GET-Methods it is:
#QueryParam("ID") String input
Which allows me to access the variable specified as ID by using input.
Everything I've found so far didn't quite address the problem I face..
For a JAXRS webservice you can create an annotated class that maps to your json e.g.
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Package {
private String packageID;
private Boolean used;
// getters and setters here
}
then ??? will be your class
public void setUsedPackage(Package package)
When you post your json you'll need to specify the Content-type header as application/json
Here's a jaxrs tutorial I found that may help
http://www.logicbig.com/tutorials/java-ee-tutorial/jax-rs/post-example/

How to handle an empty-string property name in Java

I need to use a response from a rest service returning JSON. However, one of the fields in the json response is the empty string. So, basically this:
{"wut":
{
"foo":"fooval",
"": "srsly"
}
}
So, I need to somehow translate this into a java class, as below:
#JsonIgnoreProperties(ignoreUnknown=true)
public class wut
{
#JsonProperty
private String foo;
#JsonProperty
private String <empty string???>;
//etc...
}
As you might expect, I don't have enough control over the endpoint to be able to give the property a name. Is there a way to handle this?
I'm using RestTemplate from spring to make the call, if that matters at all.

Receiving an array of Object from a web form using Spring framework

I have a form JSP web page, this form contains multiple instances of the same Java object,
I am using Java Spring Framework to control the "communication" with the controller and the view.
My problem is that I would like to be able to receive from the view a simple array containing the instances of my objects which are currently on the page (on which were probably modified).
When I want a specific kind of item, I usually just name it in my controller's method declaration, however for an array (or any Collection), this won't work.
so something like:
#RequestMapping
public String edit(...SomeObject[] objectName, ...){
}
would just return me an error, I can however receive an array of String, so this works:
#RequestMapping
public String edit(...String[] objectString, ...){
}
the goal would be to be able to make Spring automatically map the object.
thanks for your answers!
This is certainly possible; while I've not done it using #RequestMapping, I know that you can retrieve a collection it can be done with a "command" object (or #ModelAttribute)
Define a POJO with a collection attribute as your command
public class FooCommand {
private List<String> myCollection;
// Getter & Setter
}
Then access it in your controller
#RequestMapping(value = "/foo", method = RequestMethod.POST)
public String processSubmit(#ModelAttribute("fooCommand") FooCommand fooCmd) {
// do stuff with fooCmd.getMyCollection()
}
That make any sense?
Spring does not know how to create your custom object from a String so you will need to create your own PropertyEditor for your custom object.
Chapter 5 of the Spring Reference explains data binding and there is an example in Chapter 13 of how to register custom property editors in your controller.

Categories

Resources