Receiving unknown parameter name on POST request in Java (JAX-RS) - java

I have the following POST response in JAX-RS.
#POST
#Path("/save")
public Response saveS(#FormParam(key) String value) throws SQLException {
return Response.ok("TODO", MediaType.APPLICATION_JSON).build();
}
The parameter that is received could be called name or age or many other things. I have identified it as key in the code (obviously it doesn't work).
How can I retrieve the name of that parameter?
Thanks

The parameter that is received could be called name or age or many other things. I have identified it as key in the code (obviously it doesn't work).
As you already found out it doesn't work that way because the #FormParam is expecting the name of a form parameter as it is defined in the corresponding HTML form. That means you should know which form parameter you want to assign to the param (value in this case) of the method.
Here is the definition of the #FormParam annotation extracted from the JAX-RS specification:
FormParam Parameter
Specifies that the value of a method parameter is to be extracted from a form parameter in a request entity body. The value of the annotation identifies the name of a form parameter. Note that whilst the annotation target allows use on fields and methods, the specification only requires support for use on resource method parameters.
And in addition to that you should add the #Consumesannotation to your resource method as follows:
#POST
#Path("/save")
#Consumes("application/x-www-form-urlencoded")
public Response saveS(#FormParam(key) String value) throws SQLException {
return Response.ok("TODO", MediaType.APPLICATION_JSON).build();
}
Update:
I haven't tried myself, but you can try and tell me if it works. Here you should get all the params so that you can parse all the form fields:
#POST
#Consumes("application/x-www-form-urlencoded")
public void post(MultivaluedMap<String, String> formParams) {
// parse the map here
}

Related

SpringBoot: requestParam value validation when required=false

Here is my method code:
#RequestMapping(value="/api/restcall", method=GET)
public response methodcall (#RequestParam (value="testId", required=false) String testId, #RequestParam (value="requestId", required=false) String requestId){
//some code
}
I want to validate the request params. Not the value but the field itself.
API call:
localhost:8080/api/restcall?requestId=abcd&testId=xyz
I want to validate that "requestId" and "testId" are sent correctly if sent. Not the value, but the key itself. NOTE: The requestParams are not mandatory fields.
So if below API call is made:
localhost:8080/api/restcall?request=abcd&test=xyz
I want the code to validate that the requestparams are not correct. I tried the #Validate annotation and #Valid annotation. Both did not work.
When incorrect call is made like above, the code is going through as the fields are not mandatory.
I want to know what params are coming in if testId and requestId are not sent in. If I have this information, I can do the validation.
The validation of REST invocations doesn't work in this way.
This validates the values of the sent parameters, not the names of them.
So as the required attribute is set to false for the parameters, no violation constraint occurs.
The invalid names of the sent parameters are probably ignored by the Jackson processing.
If you want to perform such a validation, you should use a custom validator or a custom validation.
For example :
String errorMsg = "";
if (StringsUtil.isEmpty(testId)){
errorMsg+="testId param name missing";
}
if (StringsUtil.isEmpty(requestId)){
errorMsg+="requestId param name missing";
}
if (!errorMsg.equals("")){
throw new ValidationException(errorMsg);
}
You can get a map with all params fields and values with: #RequestParam Map<String,String> allRequestParams. Then you can use containsKey to check for a field.

Marshall object returned by #RequestBody

I have XML being fed into a REST controller and I use the #RequestBody annotation to transform that into a Java Object. I need to save the whole XML to a database column in addition to some specific elements from the Java Object. I am marshalling the Java object explicitly to accomplish this and that seems to be duplicate work. Is there a way to get the raw XML in addition to the parsed object while using the #RequestBody annotation?
Yes, there is. Let's say this is your controller method:
public Response yourControllerMethod(#RequestBody YourDTO dto) {
Simply change your #RequestBody parameter type to String and you'll get the raw body of the request:
public Response yourControllerMethod(#RequestBody String rawPayload) {
Or you can even get both:
public Response yourControllerMethod(#RequestBody YourDTO dto, #RequestBody String rawPayload) {

List of possible overloads for Jersey JAX-RS resources

I'm using Jersey to implement a JAX-RS resource. I've seen lots of different examples on Stack Overflow, various blogs and the Jersey User Guide.
I would like to know what the different overloads can be for a given resource handler. Is there a single source where these are documented?
For example, the following handles an HTTP POST request. The request body is captured as a MultivaluedMap.
#POST
public Response httpPostRequest(MultivaluedMap<String, String> body)
{
...
}
Alternatively, the following overload captures the body as a single String.
#POST
public Response httpPostRequest(String body)
{
...
}
There are other overloads too. How many are there and where are they documented?
It is just a normal Java method that has one or more annotations associated with it. The signature of the method has no particular constraints placed on it by Jersey.
Having said that, you will want to make sure that the various annotations (e.g., #Produces, #Consumes, #PathParam, #QueryParam) are applied to data types that Jersey knows how to map. For example, Jersey has no problem with mapping #PathParam to String or long. Jersey can also work with Java classes that have JAXB annotations, so your method signature can include a JAXB type combined with #Consumes(MediaType.APPLICATION_XML) and Jersey will convert the request content from an XML document to the JAXB Java class.
For example:
#GET
#Produces(MediaType.APPLICATION_XML)
#Path("somepath")
public Foos getFoosByQuery(#PathParam("businessName") String businessName,
#PathParam("businessUnitName") String businessUnitName, #PathParam("fileType") String fileType,
#QueryParam("from") String fromString, #QueryParam("to") String toString,
#DefaultValue("10") #QueryParam("interval") int intervalMinutes,
#DefaultValue("1000") #QueryParam("limit") int limit,
#DefaultValue("false") #QueryParam("errors") boolean errors) {
Here, we see that we have many parameters (with types String, int and boolean) and a return type that is a JAXB-annotated POJO. Jersey pulls the #PathParam values from the path, the #QueryParam values from the query string and converts the return value into an XML document and includes it as the content of the response.
I will also note that the name of the method can be anything we want, so the concept of "overloading" is orthogonal to Jersey. The normal Java overloading rules apply.
It should be obvious from this example that you cannot enumerate all of the possible "overloads" that you can use with Jersey.
Perhaps a different question regarding all of the possible type mappings that Jersey can do would be more in line with what you are looking for.

Jersey, JSR 303 validation - custom "path" and "invalidValue" in ValidationError

I am using Jersey (JAX-RS) and I'm trying to implement a validation. I have a problem with a response returned by my application when a validation error occurs. Now the response looks like this:
[{
"message": "Custom message",
"messageTemplate": "{custom.message.template}",
"path": "SomeJerseyResource.resourceMethod.arg0.names[0]",
"invalidValue":"[value1, value2]"
}]
where "SomeJerseyResourceClass.resourceMethod" is a JAX-RS resource:
public class SomeJerseyResource {
#POST
#Path("/path")
public Response resourceMethod(#Valid RequestModel request) {
/** method body **/
}
}
and validation constraint is assigned to a getter in RequestModel:
public class RequestModel {
private List<String> names = new ArrayList<>();
#MyConstraint
public List<String> getNames() {
return tags;
}
}
I have a custom ConstraintValidator, where I validate each element of that List.
Problem
I don't want to include resource and method name in "path" field of the response. Instead of
SomeJerseyResource.resourceMethod.arg0.names[0] I want arg0.names[0] only. Client doesn't know about server classes and methods, and he wouldn't be able to properly assign errors to fields when he receives response like that.
I want to customize "invalidValue" field of a response. More specifically, to have only invalid element value, not the whole list in that field.
I didn't find any easy way to do that. Do you have any ideas?
You can just write an ExceptionMapper<ConstraintViolationException> to return the Response of your liking. Jersey uses an ExceptionMapper<ViolationException>. ConstraintViolationException extends from ViolationException, so you're mapper is more specific, and would take precedence in the choosing of the mapper. Jersey's mapper, returns the response as a ValidationError, that's why the body is how it is. But you can make it whatever you want.
If you just want the invalidValue list, then just iterate through the ConstraintViolations from ContraintViolationException.getConstraintViolations(), and get the invalidValue from the ConstraintViolation.

Newbie: In Jersey framework, how to get HTML form object data in my case?

When client side submit a HTML form, it will send a form object to server, like:
params={username: USER_INPUT_USERNAME,
passworkd: USER_INPUT_PASSWORD}
Then, client ajax send the params object to my Jersey server.
On the server side, how can I get and parse this HTML form object data params:
#GET
#Produces({MediaType.APPLICATION_JSON})
public FormResult getFormResult(#QueryParam("params") Object params) {
//How can I define the type of the "params" I received?
//Do I need to create a Java Bean which represent the HTML form,
//and use the bean as the type of paprams? or any other way?
}
(In above code, the return type FormResult is an POJO bean which describe the result to response to client)
When I receive the params HTML form object data, how can I define the type of the params ?(above I defined it with type "Object", which is wrong).
Do I must define a POJO bean to represent the HTML form and use that bean to describe the type of the params?? or any other way in Jersey?
(If create POJO bean for the HTML form, If there are check boxes on the HTML form, the params will be an dynamic object, only checked field will be added to the params object, which is also a problem)
Anybody can help?
The #QueryParam maps an individual queryString parameter, so for a GET request you need to enumerate all your parameters as method arguments:
#GET
getFormResult(#QueryParam("name") String name, #QueryParam("age") int age, ... )
If the params that you mentioned is actually one query string parameter (http://your.rest.service?params=somethingHere), you can map that to some class that has a constructor taking a String, or a static valueOf(String) method where you do the actual parsing.
#GET
getFormResult(#QueryParam("params") FormData formData);
And the FormData class can look like this:
public class FormData {
public FormData(String s) {
// populate fields based on the content of s
}
// getters / setters / whatever ...
}
EDIT:
For checkboxes, it's not as dynamic as it looks: they have the same name, so you'll have one-, several- or no- value(s) associated with that name, depending on what the user checked. Therefore, a #QueryParam("chk") String[] checkedValues should be enough to handle the "dynamic" aspects here (actually, 'multi-valued' would be a better word).

Categories

Resources