Jersey should not consume any form parameter. exception - java

I am building rest webservice using jersey, when I add this function i got this exception, but when i remove it, the server works very good.
Customer.orderWeb(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String), should not consume any form parameter.
the code is
#Path("orderWeb/{customerID}/{restaurantID}/{IDs}/{numbers}/{descriptions}/{addressID}")
#GET
#Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN,
MediaType.TEXT_HTML, MediaType.TEXT_XML })
#Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_PLAIN,
MediaType.TEXT_PLAIN })
public String orderWeb(#FormParam("customerID") String customerID,
#FormParam("restaurantID") String restaurantID,
#FormParam("IDs") String IDs, #FormParam("numbers") String numbers,
#FormParam("descriptions") String descriptions,
#FormParam("addressID") String customerAddress) {
return "WSSSSSSSSSSSSSSSSSS";
}
it is weird because I always use path like that path. i dont know what am i doing wrong

Use #QueryParam with #GET and #FormParam with #POST

Not sure what you got fixed from the approved answer, but since I'm not seeing the answer FYI you should use #PathParam to capture path segments (not #FormParam which is to capture POST data)

if you are using #FormParam. Also make sure INPUT HTML types are using name= not id=.

Related

resteasy: #QueryParam to parse nested array structure

I'm using a javascript library called tabulator to display data inside tables on the client side.
The Tabulator js library provides a feature to encode a representation of filters in the query parameters of an ajax request. For example, here's what the query params look like:
https://host/myEndpoint?size=10&page=1&filters%5B0%5D%5Bfield%5D=username&filters%5B0%5D%5Btype%5D=like&filters%5B0%5D%5Bvalue%5D=filteredBy
Here's the same url decoded:
https://host/myEndpoint?size=10&page=1&filters[0][field]=username&filters[0][type]=like&filters[0][value]=filteredBy
If possible, I'd like to have a Resteasy endpoint like this:
#GET
#Path("/myEndpoint")
#Consumes("application/json")
#Produces("application/json")
public Response myEndpoint(#QueryParam("page") Integer page,
#QueryParam("size") Integer size,
#QueryParam("filters") List<Filter> filters) {
resteasy interprets page and size no problem, but filters is always a list of size 0.
My Filter bean has 3 fields named field, type, and value with a constructor with single String argument as described here.
But it doesn't seem like resteasy is recognizing and parsing the filters query param? Is it possible to parse this type of nested array structure query parameters in resteasy?
filters[0][field]=username&filters[0][type]=like&filters[0][value]=filteredB
I'm still hoping that there's a better way, but here's a possible solution that works for me for now at least:
#GET
#Path("/myEndpoint")
#Consumes("application/json")
#Produces("application/json")
public Response myEndpoint(#QueryParam("page") Integer page,
#QueryParam("size") Integer size,
#Context UriInfo uriInfo) {
for(String key : uriInfo.getQueryParameters().keySet()) {
// check if key starts with something like `filters[0]`
// and then parse it however you need.
}
}

chinese characters are getting corrupted as passed as query parameter values

I am using Apache cxf library and implemented rest apis.
Below is the code sample code snippet. When I pass the term value as query parameter, it is corrupting the value, but when I pass the term value as request body, everything is working fine.
#POST
#Path("/search")
#Produces({ APPLICATION_JSON })
public UserSearch searchUser(#FormParam("term") String term, #Context HttpServletRequest request) {
}
When I hit the url like "https://{SERVER_URL}/search?term=求人". It is corrupting and the term value is not passed to 'searchUer' function properly.
But when I pass the 'term' value as request body, everything is working fine.
I would like to know the reason of corruption?

Multiple resources under one request: RESTful API design pattern

I'm trying to create a GET request, where I have two different requests. Since both resources are related with each other, I'm trying to put them under one 'sub-resource'.
The first one is:
#QueryParam("{customerId}")
public List<customerModel> getCustomer(#QueryParam("customerId") Long customerId) {....}
this fetches the customer's name depending on the customerId
#QueryParam("{customerId}/details")
public List<customerDetailModel> getCustomerDetail(#QueryParam("customerId") Long customerId) {....}
this fetches the detailed information of the customer (phone number, address, etc.)
I'm running the first one with the following (works fine) :
......?customerId=7453112
but I can't reach the second request when I'm hitting the following URL:
......?customerId=7453112/details
Any suggestions?
Resource methods must be annotated with #Path and with a request method designator such as #GET, #POST, #PUT,
#DELETE, #HEAD or #OPTIONS. Your #QueryParam annotation is misplaced.
By the way, for this situation, you should consider using a path parameter instead of a query parameter. Hence you should use #PathParam instead of #QueryParam in the method parameter. For more details on when to use query or path parameters, have a look at this answer
Also, not sure why you are returning a List if you are requesting a resource by its unique identifier. In this situation, you are supposed to return a representation of a single resource (and not a represention of multiple resources).
So your resource class would be as following:
#Path("customers")
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public class CustomerResource {
#GET
#Path("{customerId}")
public CustomerModel getCustomer(#PathParam("customerId") Long id) {
...
}
#GET
#Path("{customerId}/details")
public CustomerDetailModel getCustomerDetail(#PathParam("customerId") Long id) {
...
}
}
The first endpoint can be requested as following:
GET http://example.com/api/customers/1
And the second endpoint can be requested as following:
GET http://example.com/api/customers/1/details
You need to go with #RequestMapping.
Something like:
#RequestMapping("/{customerId}") and #RequestMapping("/{customerId}/details").
Your URL becomes 7453112/details instead of query params.
You can specify the /details in an #Path annotation, and then use the same query parameter, like this:
#Path("/details/{customerId}")
public List<customerDetailModel> getCustomerDetail(#PathParam("customerId") Long customerId) {....}
Then your URL would look like this:
.../details/7453112
Or if you want to keep using it as a query parameter you can do something like this:
#Path("/details")
public List<customerDetailModel> getCustomerDetail(#QueryParam("customerId") Long customerId) {....}
using this url:
.../details?customerId=xxx

CXF doesn't match the right target method depending of QueryParam arguments

I'm writing a RESTful Web-Service but CXF doesn't match the right target method when the URI paths are identical but only #QueryParam parameters are different...
I know that #QueryParam parameters are optional and as it's said in the answer of this post: "both methods are ambiguous [at URI paths level] and seems like the first one wins"...
ex: http://mydomain/property?key=sthA or http://mydomain/property?value=sthB, CXF will match the same method unfortunately.
#Path("/property")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public interface PropertyService {
#GET
#Path("/{id}")
AppSetting findPropertyById(#PathParam("id") String id); /* /property/123 */
#GET
Property findPropertyByKey(#QueryParam("key") String key); /* /property?key=sth */
#GET
List<Property> getPropertiesByValue(#QueryParam("value") String value); /* /property?value=sth */
}
So, what is the best solution between:
having one method that will handle any possible #QueryParam parameters for a specific URI path (here "/property?[key=sthA][&value=sthB][...]")
or set some RegExp directly in the value of the #Path annotation to "help" CXF to match URI path with the right method (here: "/property?key=sthA" should match the method with "#Path({key:.*})" annotation)
or any other possible solution
?
Thks

Can RestEasy choose method based on query params?

I've started working with RestEasy and I've come across a problem that I can't seem to find an answer to. If I have 2 methods that both resolve to the same path (in this case /path1/path2/path3), but they both have a different number of query parameters, will RestEasy be able to determine which method to use?
#GET
#NoCache
#Produces({
MediaType.APPLICATION_JSON
})
#Path("/path1/path2/{path3}")
public String getResults1(
#PathParam("path3") String path3,
#QueryParam("query1") #DefaultValue("") String query1,
#QueryParam("query2") String query2,
#QueryParam("query3") #DefaultValue("25") int query3) {
...
}
#GET
#NoCache
#Produces({
MediaType.APPLICATION_JSON
})
#Path("/path1/path2/{path3}")
public String getResults2(
#PathParam("path3") String path3,
#QueryParam("query1") #DefaultValue("") String query1,
#QueryParam("query2") #DefaultValue("5") Integer query2) {
...
}
I've done some testing and yesterday it seemed that everything was working perfectly and that it could choose the right path, but now today I'm starting to see it take the wrong path each time.
Is this something that should be handled, or should I just suck it up and put it in 1 method and do the check myself?
No, you should be handling this in the method. If conflicting resources are found it is implementation independent which method will be matched.
Take a look at your example again:
If you submitted query1 and query2 how would it know if you wanted the method with 2 query parameters or the method with 3 query parameters and you wanted it to default the 3rd to it's default value?

Categories