I have a REST API which accepts MediaType.MULTIPART_FORM_DATA.
I know I can use something like #FormDataParam("field1") String field1 to get to form field values in my rest API code.
What I want to know is that is there any way I can handle case where number of form fields is not fixed. ie. form submitter can add more input fields from UI and then post that form. So in my REST API I can never take a call how many fields will be coming.
How can this be handled in jersey?
thanks,
Sandeep
Get away with #FormParam in jersey and use the context field. Something like
#Context
private HttpServletRequest request;
#POST
#Path("/testForSandeep")
#Produces("application/xml")
public String func() throws IOException
{
//gives you all params
final Map<String, String[]> params = request.getParameterMap();
//you can iterated and get whatever you want
for(String fieldName : params.keySet())
{
String[] fieldValues = params.get(fieldName);
}
//more code
}
Related
I'm trying to check if my method works through the API
#GetMapping(value = "/ads/in/rubrics/{ids}")
public List<Ad> findAllAdInRubricByIds(#PathVariable("ids") List<Integer> ids) {
return adService.findAllAdInRubricByIds(ids);
}
how can i set some parameters in get request?
that's how i tried
http://localhost:9999/mvc/ad/ads/in/rubrics/ids&ids=1&ids=2
http://localhost:9999/mvc/ad/ads/in/rubrics/ids&ids1=1&ids2=2
always get error 400 Bad Request
You're confusing PathVariables with RequestParams.
A PathVariable is a variable in the request path. It doesn't need to be the last character.
#GetMapping("/api/{version}/foo/{idFoo}")
public Void getFooNumber(#PathVariable("version") Integer version, #PathVariable("idFoo") Integer idFoo){
return "1";
}
Since PathVariables are part of the path, they're always required. If you don't incluide them in the request you'll end up invoking another endpoint or getting a 404 if the request can't be mapped to any endpoint.
The RequestParams are the parameters received at the end of the request URL, after the "?" character.
#GetMapping("/api/foo")
public Void getFooNumber(#RequestParam(value="version", required=false) Integer version, #RequestParam(value="idFoo", required=true) Integer idFoo){
return "1";
}
With RequestParams you can define for each one of them if it's required or not.
You can also mix them and have in the same method PathVariables and RequestParams.
In the first example the request URL would be ".../api/1/foo/25", while in the second example it would be ".../api/foo?version=1&idFoo=25"
As for having an array or a list, if you define the parameter as a List you can send multiple parameters of the same name:
#GetMapping("/ads/in/rubrics")
public Void findAllAdInRubricByIds(#RequestParam(value="ids", required=true) List<Integer> ids){
return adService.findAllAdInRubricByIds(ids);
}
In this case, you can use ".../ads/in/rubrics?ids=1&ids=2&ids=3&ids=4"
http://localhost:9999/mvc/ad/ads/in/rubrics/?ids1=1&ids2=2
For the first parameter use a ? and after that for each additional parameter a &
My main question is how to pass a (Map, String) to a REST API, I know if I use #RequestBody all the passed contents are stored to map but what can be done to pass map as well as any other parameters REST API.
#GetMapping(path="/invoices")
public String invoiceReceived( Map<String,Object> invoice,String format) throws MessagingException {
System.out.println(format); // this prints NULL
return "returnValue";
}
So I tried using PathVariable but they throw exception. What can be done?
#GetMapping(path="/invoices/{invoiceData}/{format}")
public String invoiceReceived(#PathVariable("invoiceData") Map<String,Object> invoice,
#PathVariable("format") String format) throws MessagingException {
System.out.println(format); // this prints NULL
return "returnValue";
}
What should I do to accept a map and a variable as input? And what should be the JSON file look like which should be given as input?
{
"invoiceData":[{"invoiceId":"23642",
"clientName":"Client",
"amount":"23742.67",
"email":"client#abc.com"
}],
"format":"html"
}
This question was identified similar to another question, So I am trying to explain how is this different, I know that I can use #RequestBody to get all the variables in the map, but The call will be made with two parameters some of which will be stored in map but one parameter will be used for another variable. So how can I send a map along with any other variable?
I think you can use query strings and path variables.
If you declare a controller's method like:
#GetMapping(path="/invoices")
public String invoiceReceived(#RequestBody Map<String,Object> invoice, #RequestParam String format) {
...
}
the url to which the request is send and the JSON request body will be something like below.
The url:
http://localhost:8080/invoices?format=html
The JSON request body:
{
"invoiceId":"23642",
"clientName":"Client",
"amount":"23742.67",
"email":"client#abc.com"
}
Also you can use a path variable like:
http://localhost:8080/invoices/html
#GetMapping(path="/invoices/{format}“)
public String invoiceReceived(#RequestBody Map<String,Object> invoice, #PathVariable String format) {
...
}
I have to transform a very peculiar JSON payload into POJOs manually. I thought I could put the JSON string into a String entity:
#ApiMethod(
name = "postSomething",
path = "postSomething/{id}",
httpMethod = ApiMethod.HttpMethod.POST
)
public void postSomething(#Named("id") Integer id, HttpServletRequest request, String data) {
//Parse data here...
}
When I do that, I get an error: MissingParameterNameException: Missing parameter name. Parameter type (class java.lang.String) is not an entity type and thus should be annotated with #Named.
I tried to use an #ApiTransformer but I get a similar error.
Could you please give me an example of parsing the JSON content manually?
The error message says that String data needs to have an #Named annotation, similar to Integer id.
I worked around this issue by using a Collections class instead of String and manual parsing:
#ApiMethod(
name = "postSomething",
path = "postSomething/{id}",
httpMethod = ApiMethod.HttpMethod.POST
)
public void postSomething(#Named("id") Integer id, HttpServletRequest request, HashMap<String,String> data) {
//Parse each item of data here...
}
From this, I can parse each item inside the data. The values contain a hierarchy of either other collections (List for an array, Map for a JSON entity) or String for an actual value. So by doing this I don't need to use any other JSON parsing library such as Jackson.
String is not an #Entity object so it can't be passed as a parameter (a data parameter) to the endpoints API without proper annotation (like #Name or #Nullable). Either you must remove it from the method declaration or annotate it with #Name or #Nullable.
My understanding so far is on our controller request mapping method we can specify RedirectAttributes parameter and populate it with attributes for when the request gets redirected.
Example:
#RequestMapping(value="/hello", method=GET)
public String hello(RedirectAttributes redirAttr)
{
// should I use redirAttr.addAttribute() or redirAttr.addFlashAttribute() here ?
// ...
return "redirect:/somewhere";
}
The redirect attributes will then be available on the target page where it redirects to.
However RedirectAttributes class has two methods:
addAttribute()
addFlashAttribute()
Have been reading Spring documentation for a while but I'm a bit lost. What is the fundamental difference between those two, and how should I choose which one to use?
Here is the difference:
addFlashAttribute() actually stores the attributes in a flashmap
(which is internally maintained in the users session and removed
once the next redirected request gets fulfilled)
addAttribute() essentially constructs request parameters out of
your attributes and redirects to the desired page with the request
parameters.
So the advantage of addFlashAttribute() will be that you can store pretty much any object in your flash attribute (as it is not serialized into request params at all, but maintained as an object), whereas with addAttribute() since the object that you add gets transformed to a normal request param, you are pretty limited to the object types like String or primitives.
Assume you have 2 controllers.If you redirect from one controller to
another controller the values in model object won't be available in the
other controller. So if you want to share the model object values
then you have to say in first controller
addFlashAttribute("modelkey", "modelvalue");
Then second controller's model contains now the above key value pair..
Second question ? What is difference between addAttribute and addFlashAttribute in RedirectAttributes class
addAttribute will pass the values as requestparameters instead of model,so when you add some using addAttribute you can access those values from request.getParameter
Here is the code.I have used to find out what is going on :
#RequestMapping(value = "/rm1", method = RequestMethod.POST)
public String rm1(Model model,RedirectAttributes rm) {
System.out.println("Entered rm1 method ");
rm.addFlashAttribute("modelkey", "modelvalue");
rm.addAttribute("nonflash", "nonflashvalue");
model.addAttribute("modelkey", "modelvalue");
return "redirect:/rm2.htm";
}
#RequestMapping(value = "/rm2", method = RequestMethod.GET)
public String rm2(Model model,HttpServletRequest request) {
System.out.println("Entered rm2 method ");
Map md = model.asMap();
for (Object modelKey : md.keySet()) {
Object modelValue = md.get(modelKey);
System.out.println(modelKey + " -- " + modelValue);
}
System.out.println("=== Request data ===");
java.util.Enumeration<String> reqEnum = request.getParameterNames();
while (reqEnum.hasMoreElements()) {
String s = reqEnum.nextElement();
System.out.println(s);
System.out.println("==" + request.getParameter(s));
}
return "controller2output";
}
Javadoc description:
"A FlashMap provides a way for one request to store attributes intended for use in another. This is most commonly needed when redirecting from one URL to another -- e.g. the Post/Redirect/Get pattern. A FlashMap is saved before the redirect (typically in the session) and is made available after the redirect and removed immediately."
I am using Jersey for Rest and have a method that accepts #QueryParam.
However, the users may send #QueryParam. like this:
contractName# where # is a number from 0-155.
How can I define it in QueryParam (like regex expression)?
You can't specify the regexp. However, you can define a custom Java type to represent that query param and implement your own conversion from String to that type - see http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e255 (example 2.15).
I don't think you can do it with QueryParam, but you can get the list of parameters directly:
#GET
public String get(#Context UriInfo ui) {
MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
}
and iterate through that looking for keys that match your regular expression.
#GET
public String get (#QueryParam(value="param") String param){
boolean test =testYourParamWithNativeRegexpTools(param);
if( test==false)return 400;
else //work
.....
}