My requirement is as follows:
I want to give actor name, start date, end date and get all the films he acted in that period.
For that reason, my service request is like this.
http://localhost:8080/MovieDB/GetJson?name=Actor&startDate=20120101&endDate=20120505
Now, i want to improve it.
I want to give a start date, end date and more than one actor name and want to see all those actors movies in that period.
I am not sure how should my url look to support such thing.
I am writing a java based web service using spring.
Below code is to support one actor
#RequestMapping(value = "/GetJson", method = RequestMethod.GET)
public void getJson(#RequestParam("name") String ticker, #RequestParam("startDate") String startDate, #RequestParam("endDate") String endDate) {
//code to get results from db for those params.
}
One solution i am thinking is using a % symbol to seperate actor names. For example:
http://localhost:8080/MovieDB/GetJson?name=Actor1%Actor2%Actor3&startDate=20120101&endDate=20120505
Now, in the controller i will parse the name string with % and get back all actors names.
Is this a good way to do this or is there a standard approach?
Thanks
Separate with commas:
http://localhost:8080/MovieDB/GetJson?name=Actor1,Actor2,Actor3&startDate=20120101&endDate=20120505
or:
http://localhost:8080/MovieDB/GetJson?name=Actor1&name=Actor2&name=Actor3&startDate=20120101&endDate=20120505
or:
http://localhost:8080/MovieDB/GetJson?name[0]=Actor1&name[1]=Actor2&name[2]=Actor3&startDate=20120101&endDate=20120505
Either way, your method signature needs to be:
#RequestMapping(value = "/GetJson", method = RequestMethod.GET)
public void getJson(#RequestParam("name") String[] ticker, #RequestParam("startDate") String startDate, #RequestParam("endDate") String endDate) {
//code to get results from db for those params.
}
Related
If i have something like
#GetMapping(value = "/list")
public ResponseEntity<MyDTO> findStatusPerEC(#RequestParam final List<Long> numbersEC)
How do I add numbersEC in my url on the frontend? Is this query parameter?
I know this one was for old call that didnĀ“t had query parameters and data was only a number (long)
return this.http.get<any>(URL_API + '/simulator/status/' + data);
But now I have to send a list of long values...may you help me?
return this.http.get<any>(URL_API + '/simulator/status/' + data);
Since you mentioned data is only a long type, what you are referring to here when you make the above request is a PathVariable it is slightly different to a RequestParam.
Path variables have the syntax: /simulator/status/:statusID where statusID is dynamic and extracts values from the URI.
Request parameters have the syntax: ?arg=val&arg2=val2 etc... and extract values from the request query string.
Solution
To answer your question, to send an array across as request parameters, you can do it like so:
?myparam=myValue1&myparam=myValue2&myparam=myValue3
As you can see, above myparam is unchanging, and the values are variable, hence the data within your list data structure.
So when you're making your request it will look similar to this:
Angular/Javascript
return this.http.get<any>(URL_API + '/list' + '?myparam=myValue1&myparam=myValue2&myparam=myValue3');
Java
#GetMapping(value = "/list")
public ResponseEntity<MyDTO> findStatusPerEC(#RequestParam final List<Long> numbersEC)
I hope this helps.
I have a rest service which validates date now i need to modify it to take two dates, but i don't know if to use #PathParam or #QueryParam and if i can insert it between two #PathParam
This it the original code :
#Path("isDateValid/{date}/{itemId}")
public boolean isDateValid(#PathParam("date") Date date, #PathParam("itemId") Long itemId) {
Should i do like this :
#Path("isDateValid/{startDate}/{endDate}/{itemId}")
public boolean isDateValid(#PathParam("startDate") Date startDate, #PathParam("endDate") Date endDate, #PathParam("itemId") Long itemId) {
If you do not want to use third party stuff, I suggest you define a format for the text-date. You can use the SimpleDateFormat class (avoid the space). The you can use the following code.
#Path("isDateValid/{itemId}")
public boolean isDateValid(#PathParam("itemId") Long itemId) {
#QueryParam("begin") String sBegin;
#QueryParam("end") String sEnd;
SimpleDateFormat sdf = new SimpleDateFormat(/* Your patern, for example "yyMMddHHmmssZ"*/);
Date dBegin = sdf.parse(sBegin);
Date dEnd = sdf.parse(sEnd);
/*
...
*/
}
Date Class is cannot serialize using JAX-RS as it is not a simple type. You need to develop the same using MessageBodyReader/Writer .
Click Here for more
Or you can use some third party stuff to configure to get it done.
Click Here for more
When using Spring MVC, is there a way to create two entry points by whether or not any query string has been supplied in the request.
Something like below where * is a wildcard?
#RequestMapping(value = "/page", method = RequestMethod.GET, params = {"*"})
public String getResourceWithQuery(...)
#RequestMapping(value = "/page", method = RequestMethod.GET, params = {"!*"})
public String getResourceWithoutQuery(...)
Is this possible with Spring?
Edit: To be clear, I'm not looking for a particular query parameter, I'm looking to separate the methods by the existence of any query string being present at all.
The fall back is to have one method and then check in code for query parameters and split accordingly. Having a filter method like this is messy and I'd prefer not to have to do this. Unfortunately the splitting functionality by query pattern is common in my code as it is required by the business.
One end point is enough.
You can set default value for request parameter(or query string), this will make request parameter optional.
As per java doc,
defaultValue:
public abstract String defaultValue The default value to use as a fallback > when the request parameter is not provided or has
an empty value. Supplying a default value implicitly sets required()
to false.
For example,
public String doSomething(#RequestParam(value = "name", defaultValue = "anonymous") final String name) {
Your are trying to map the request URI which having the query string or not.you are using the params in #RequestMapping which actually use for narrow the Request matching.Read below link
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params--
.By using below code you can accept anything after ~/page/ URI.I hope this will help
#RequestMapping(value = "/page/**", method = RequestMethod.GET)
public String getResourceWithQuery(...)
I am using a query parameters to set the values needed by the Google Maps API.
The issue is I do not need the & sign for the first query parameter.
#GET("/maps/api/geocode/json?")
Call<JsonObject> getLocationInfo(#Query("address") String zipCode,
#Query("sensor") boolean sensor,
#Query("client") String client,
#Query("signature") String signature);
Retrofit generates:
&address=90210&sensor=false&client=gme-client&signature=signkey
which causes the call the fail when I need it to be
address=90210&sensor=false&client=gme-client&signature=signkey
How do I fix this?
If you specify #GET("foobar?a=5"), then any #Query("b") must be appended using &, producing something like foobar?a=5&b=7.
If you specify #GET("foobar"), then the first #Query must be appended using ?, producing something like foobar?b=7.
That's how Retrofit works.
When you specify #GET("foobar?"), Retrofit thinks you already gave some query parameter, and appends more query parameters using &.
Remove the ?, and you will get the desired result.
I am new to retrofit and I am enjoying it. So here is a simple way to understand it for those that might want to query with more than one query: The ? and & are automatically added for you.
Interface:
public interface IService {
String BASE_URL = "https://api.test.com/";
String API_KEY = "SFSDF24242353434";
#GET("Search") //i.e https://api.test.com/Search?
Call<Products> getProducts(#Query("one") String one, #Query("two") String two,
#Query("key") String key)
}
It will be called this way. Considering you did the rest of the code already.
Call<Results> call = service.productList("Whatever", "here", IService.API_KEY);
For example, when a query is returned, it will look like this.
//-> https://api.test.com/Search?one=Whatever&two=here&key=SFSDF24242353434
Link to full project: Please star etc: https://github.com/Cosmos-it/ILoveZappos
If you found this useful, don't forget to star it please. :)
public interface IService {
String BASE_URL = "https://api.demo.com/";
#GET("Login") //i.e https://api.demo.com/Search?
Call<Products> getUserDetails(#Query("email") String emailID, #Query("password") String password)
}
It will be called this way. Considering you did the rest of the code already.
Call<Results> call = service.getUserDetails("abc#gmail.com", "Password#123");
For example when a query is returned, it will look like this.
https://api.demo.com/Login?email=abc#gmail.com&password=Password#123
Question is pretty self explanatory. I want to send 2 different arrays of objects through a POST form without ajax to my controller.
I changed my question to using ajax and using a get request due to the size of the params. Currently getting a 400 (Bad Request). I have no idea why. Please take a look...
I have objects:
var phone = {phoneId:"", phoneNumber:"", phoneType:""};
var schedule = {scheduleId:"", time:"", day:""};
Which I place into a javascript arrays:
var phones = [phone1, phone2, phone3];
var schedules = [schedule1, schedule2];
and I use ajax to send:
var data = {
index: id,
schedules: schedules,
phones: phones
}
var url = "/myController/myUrl"
$.getJSON(url, data, function(result){
if(result.ok){
$('#messageAlertSuccess').show();
} else {
$('#messageAlertError').show();
}
});
I created wrapping classes to map them like so:
public class PhoneWrapper(){
private String phoneId;
private String phoneNumber;
private String phoneType;
}
And of course the scheduleWrapper follows the same convention.
Here's the method in my controller:
#ResponseBody
#RequestMapping(value="/myUrl", method=RequestMethod.GET)
public Result doSomething(#RequestParam("index") int index,
#RequestParam("phones") Set<PhoneWrapper> phoneWrappers,
#RequestParam("schedules") Set<ScheduleWrapper> scheduleWrappers,
Model model,
HttpSession session){
//do stuff here.
}
I am currently getting a 400. So what's wrong?
Update: here's the url that the .getJSON jquery method is building:
http://localhost:8080/myApp/myController/myUrl?index=9&schedules%5B0%5D%5BscheduleId%5D=1&schedules%5B0%5D%5BfromDay%5D=Monday&schedules%5B0%5D%5BtoDay%5D=Friday&schedules%5B0%5D%5BfromTime%5D=08%3A30%3A00&schedules%5B0%5D%5BtoTime%5D=16%3A00%3A00&schedules%5B1%5D%5BscheduleId%5D=5&schedules%5B1%5D%5BfromDay%5D=Saturday&schedules%5B1%5D%5BtoDay%5D=Monday&schedules%5B1%5D%5BfromTime%5D=09%3A00%3A00&schedules%5B1%5D%5BtoTime%5D=13%3A00%3A00&phones%5B0%5D%5BphoneId%5D=6&phones%5B0%5D%5BphoneNumber%5D=787-788-1111&phones%5B0%5D%5BphoneType%5D=PHONE&phones%5B1%5D%5BphoneId%5D=106&phones%5B1%5D%5BphoneNumber%5D=787-795-4095&phones%5B1%5D%5BphoneType%5D=FAX
I see a few things that don't look right
unless you have getters and setters in your wrappers (DTO is a better name), i don't use them for my DTOs for xhr calls, you need to change
public class PhoneWrapper(){
private String phoneId;
private String phoneNumber;
private String phoneType;
}
to have public fields vs private
public class PhoneWrapper(){
public String phoneId;
public String phoneNumber;
public String phoneType;
}
Your js arrays are not arrays but objects;
var phones = {phone1, phone2, phone3};
var schedules = {schedule1, schedule2};
Here they are as arrays
var phones = [phone1, phone2, phone3];
var schedules = [schedule1, schedule2];
Make sure you naming is the same of both the js and java sides. I find it very helpful to turn on the debugging when troubleshooting these problems. log4j -
<logger name="org.springframework.web.servlet.mvc" >
<level value="debug" />
</logger>
EDIT
So after the question was updated with more info I notice that it was the same problem as Binding a list in #RequestParam
I would say that you are almost there! The first thing the you need is a wrapper to hold the two Set<> parameters since spring is not able to map a collection directly to parameters (yet?).
Also, there are two ways to handle this kind of requests:
use a json request and #Requestbody with a single javascript object in the request body an map this into a java class (automatically by spring). This means you need to change a little how the data is send down and this approach has one side effect: you cannot merge data simply by defining the parameter as a model attribute.
a second possibility is to stay with the post form submit. Also here you need to create the wrapper and use this one as a requestparam. Either one per Set<> parameter like #Sotirios mentioned in his answer or one parameter which holds both sets. Then you need to modify your submit data to send the phone and schedule information like input fields. I haven't used sets in this case but
lists and the parameter names would look like phoneWrapper[0].phoneId.
The advantage of the second approach is that you can merge the request data with existing values so you do not need to send down a complete phone information all the time.
var phones = {phone1, phone2, phone3};
var schedules = {schedule1, schedule2};
These two are not arrays (square brackets), but objects (curly brackets).
Compare with
var phones = ["phone1", "phone2", "phone3"];
var schedules = ["schedule1", "schedule2"];
and if you are to pass actual object references (phone1, phone2, phone3, schedule1 and schedule2 are object variables) then you need to use
var phones = [phone1, phone2, phone3];
var schedules = [schedule1, schedule2];
For spring the map request parameters to Class instance fields, they have to match the name of the parameter.
So with
<input type="hidden" name="someParameter" value="123"/>
and
public class SomeClass {
private String someParameter;
// getters and setters
}
a Spring controller will be able to be injected with a SomeClass instance whose field someParameter has the value 123 that comes from the html hidden input request parameter. This is also known as a command object.
A javascript array has no meaning to either html or http.
As for the solution, I would keep your class PhoneWrapper, use javascript to populate 3 <input> elements, and change the method definition to
#RequestMapping(value=MY_URL, method=RequestMethod.POST)
public String doSomething(#RequestParam("index") int index,
PhoneWrappers phoneWrappers,
ScheduleWrappers scheduleWrappers,
Model model,
HttpSession session){
Notice there are no more array [] brackets. (You would do the same for ScheduleWrappers).