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/
Related
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.
I have the following Jax-RS end-point:
#XmlRootElement(name = "foobar")
public class Foobar {}
#GET
#Produces(MediaType.APPLICATION_XML)
public Object getFoobars() {
return new GenericEntity<List<FooBar>>(service.getFooBars());
}
Using Jersey 1.x, it used to return:
<foobars>
<foobar>...</foobar>
<foobar>...</foobar>
</foobars>
Now that I use RestEasy, it returns:
<collection>
<foobar>...</foobar>
<foobar>...</foobar>
</collection>
How can I control the root name of a returned GenericEntity<List<X>> in Jax-RS (using Rest-Easy)?
Please note that I also return Json format and I need to keep the API backward-compatible (for exemple the root element is an array in Json and should stay the same)
Found the solution myself after digging a bit in the RestEasy source code. You just have to add the #Wrapped(element="___") annotation to the method:
import org.jboss.resteasy.annotations.providers.jaxb.Wrapped;
#GET
#Produces(MediaType.APPLICATION_XML)
#Wrapped(element = "foobars")
public Object getFoobars() {
return new GenericEntity<List<FooBar>>(service.getFooBars());
}
Works correctly for XML and properly ignored for JSON.
I cannot find a way to fix this issue, but... maybe it's not an issue.
I use Extjs as the front-end and Spring MVC as backend, the Ajax request looks like:
{"isOk": true}
The Mapping DTO is:
public class TestDTO implements Serializable {
private static final long serialVersionUID = -6074462313103219627L;
private Boolean isOK;
public Boolean isOk(){...}
Public void setOk(Boolean isOk){...}
}
The get/set method be generated by intellij idea, as you can imagine that jackson works fine if I add #JsonProperty("isOk") under the "setOk" method.
But I have a lot of ***DTO objects, so is there a convenient method to reslove this issue? thanks.
I have checked the "com.fasterxml.jackson.databind.SerializationFeature" class, and didn't find any config which like the "compatible_boolean_and_ignore_is_keyword" etc..
I didn't test it, but might be helpful for your case:
https://stackoverflow.com/a/35088196/677937
Basically, try to rename your getter/setter to:
getIsOk / setIsOk
It should then serialize/deserialize json in form of {"isOk": ... }
It's been some time since I used spring, but if I recall correctly you have to
annotate the class with #Entity
implement the Serializable interface (class DTO implements Serializable)
provide a default constructor
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
Forgive me if I am asking an obvious question (maybe I missed it in the docs somewhere?) but has anyone found a good way to organize their URLs in Jersey Java framework?
I mean organizing them centrally in your Java source code, so that you can be sure there are not two classes that refer to the same Url.
For example django has a really nice regex-based matching.
I was thinking of doing something like an enum:
enum Urls{
CARS ("cars"),
CAR_INFO ("car", "{info}");
public Urls(String path, String args)
...
}
but you can imagine that gets out of hand pretty quickly if you have urls like:
cars/1/wheels/3
where you need multiple path-ids interleaved with one another...
Any tips?
From my experiences with Jersey, when I tried to annotate two places with the same #Path, I had compilation errors and it wouldn't run. This might not always be the case, so the following might help:
You can get an application.wadl file from your Jersey app by simply requesting it from you web resource:
$ curl http://localhost:8080/application.wadl
or if you prefixed your web services under /ws/
$ curl http://localhost:8080/ws/application.wadl
The application.wadl file is an XML file that shows you all of your resources in your running application, as well as what methods you can call on a resource. See the following resource on how this file is laid out.
Well - I assume you have a #Path on each resource? This means you don't have to keep track of URLs across your entire application, rather just within each class - which is relatively easy if you annotate the interface.
Using enums won't work - you can only put contants into an annotation, but using a class holding final static String could work.
public class UrlConst {
public final static RESOURCE_MY_RESOURCE="/resource";
public final static RESOURCE_MY_RESOURCE2="/resource";
public final static OP_GET_ALL="/";
public final static OP_GET_BY_ID="/{id}";
}
#Path(UrlConst.RESOURCE_MY_RESOURCE)
public interface MyResource {
#GET
#Path(UrlConst.OP_GET_ALL)
#Produces(MediaType.APPLICATION_XML)
public ObjectList getAll();
#GET
#Path(UrlConst.OP_GET_BY_ID)
#Produces(MediaType.APPLICATION_XML)
public Object get(#PathParam("id") int id);
}
#Path(UrlConst.RESOURCE_MY_RESOURCE2)
public interface MyResource2 {
#GET
#Path(UrlConst.OP_GET_ALL)
#Produces(MediaType.APPLICATION_XML)
public ObjectList getAll();
#GET
#Path(UrlConst.OP_GET_BY_ID)
#Produces(MediaType.APPLICATION_XML)
public Object get(#PathParam("id") int id);
}
etc.