Spring #Cacheable how to configure a complex key - java

I have a method that returns a list and I want to cache it based on the parameters passed.The parameters are 4 and integers how can I configure this with SpEL?
I am using spring version 4.0.6.RELEASE.

You can use something like this
#Cacheable(value ="CacheService", key="#par1 + #par2 +#par3 +#par4" )

The default is to use all the parameters of the method, whose return value is cached.
For example.
#Cacheable(value ="CacheService")
public ReturnType methodName(int param1, int param2, int param3, int param4) {
//method body
}

You can use the class SimpleKey (org.springframework.cache.interceptor.SimpleKey):
#Cacheable(value="getPerson", key="new SimpleKey(#id, #age, #socialSecNo)")
public String getPerson(Integer id, Integer age, Integer socialSecNo){
...
}

Related

Spring Boot handling multiple parameters in a get request

I am new to using Spring boot framework.
I want to create a #GetMapping where based on what user enters in the parameter either Property1 Name(String) or Protery2 Designation(String) or Property3 Salary(Integer) the method should be able to get the List of employees based on one or more properties.
I can create individual methods but I do not want to do that.
I want to do something like this:
#GetMapping("/employee")
public List<Employee> getEmployee(Params parameters)
{
// Filter the list based on parameters provided and return the list
}
Also, I am not understanding how to handle parameters
for example, if it is an integer there is only one column but if the user enters string there are two columns.
If the user does not specify the parameter name I have to handle that.
You can use #RequestParam Map<String, String> params to bind all parameters to one variable
E.g.
#RequestMapping(value="/params", method = RequestMethod.GET)
public ResponseEntity getParams(#RequestParam Map<String, String> params ) {
System.out.println(params.keySet());
System.out.println(params.values());
return new ResponseEntity<String>("ok", HttpStatus.OK);
}
You can define the three parameters using the #RequestParam annotation and check which one is non-empty:
#GetMapping("/employee")
public List<Employee> getEmployee(#RequestParam(defaultValue = "empty") String name, #RequestParam(defaultValue = "empty") String designation, ....
{
// check which one is not empty and perform logic
if (!name.equals("empty")) {
// do something
}
}
Regarding which parameter the user chooses: you can make a drop-down menu or a simple-radio selection, where the user chooses the search criteria himself (and where each criterion is mapped by a request parameter). For example:

How to add to add a parameter with multiple values using retrofit? including #Field and #Query

this is the url I want to add:
/survey/add?moderator_id=1&password=123456&visitor_name=nabil&visitor_mobile=123456&entity_id=32&visitor_gender=male&survey={"opinion":"great event","answers":[{"answer":1,"question_id":9},{"answer":1,"question_id":10},{"answer":1,"question_id":11}]}
i want to add the last parameter to the my post request, how to do that!
this is the post request:
public interface Serviecs {
#POST("survey/{add}")
#FormUrlEncoded
Call<SubmitSurvey> getSubmit(#Path("add") String add,
#Field("moderator_id") int moderator_id,
#Field("visitor_name") String visitor_name,
#Field("visitor_mobile") String visitor_mobile,
#Field("entity_id") int entity_id,
#Field("visitor_gender") String visitor_gender
);
}
Call<SubmitSurvey> getSubmit(#Path("add") String add,
#Field("moderator_id") int moderator_id,
#Field("visitor_name") String visitor_name,
#Field("visitor_mobile") String visitor_mobile,
#Field("entity_id") int entity_id,
#Query ReqAnsQues visitor_gender
);
And the structure of ReqAnsQues
Class ReqAnsQues{
#SerializedName("answer")
String answer;
#SerializedName("visitor_gender")
String visitorGender;
}
#Field requires a mandatory parameter. In cases when #Field is optional, we can use #Query instead and pass a null value

How to give default value as integer in #RequestParam()

I'm new to spring boot and learning #RequestParam()
I know that we can give defaultValue in String but when I am trying to give default value as Integer it's showing me an error.
#RequestMapping("/returnVeriable")
public int getVeriable(#RequestParam(required=true,defaultValue=1/*error here*/) int veri){
return veri;
}
any help would be appreciated.
Try with "" around integer to make it string as the defaultValue is implemented as String.
#RequestMapping("/returnVeriable")
public int getVeriable(#RequestParam(required=true,defaultValue="1") Integer veri){
return veri;
}
refer : https://jira.spring.io/browse/SPR-5915
When a value traffic by HTTP protocol, it has no type. It's a String. And so it is at this parameter type at the annotation. Then, you do something like this:
#RequestParam(required = true, defaultValue = "1") Integer veri
And it will work fine.
This should work
#RequestMapping("/returnVariable")
public int getVariable(#RequestParam(required=true,defaultValue="1") int var) {
return var;
}
By default what ever you pass to the controller is treated as String and converted to respective types. So even default values need to be set as String

spring boot not registering optional GET parameter

I am following a tutorial and I have the following method:
#RequestMapping(value = "/viewstatus", method = RequestMethod.GET)
ModelAndView viewStatus(ModelAndView modelAndView, int pageNumber) {
System.out.println();
System.out.println("===========" + pageNumber + "===========");
System.out.println();
modelAndView.setViewName("app.viewStatus");
return modelAndView;
}
However when I go to http://localhost:8080/viewstatus?p=11 I get the following error:
Optional int parameter 'pageNumber' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
I changed the int parameter to Long but then I get the following output in the console when I navigate to the same page:
===========null===========
The parameter is null, so it's basically not being recognized, but as far as I can tell I am following the tutorial to the letter, can you see a problem with my code?
Add a #RequestParam annotation to map the url variable to the method argument
public ModelAndView viewStatus(ModelAndView modelAndView,
#RequestParam("p") int pageNumber) {
Use #RequestParam in the signature of your method, before the type and name of the parameter. The name must match with the url param. Remember that you have to use Wrapper classes because primitive types doesn't support null values.
ModelAndView viewStatus(
ModelAndView modelAndView,
#RequestParam(value = "p", required=false) Integer pageNumber
){
//...
}
First use #RequestParam annotation to map the GET value to method argument. Then if you want to make that parameter optional you can specify the required attribute of #RequestParam to false.
If you want to assign some default value to params you can use defaultValue attribute.
Note: If your GET params KEY name equals to Method Argument name then you don't have to use value attribute.
ModelAndView viewStatus(
ModelAndView modelAndView,
#RequestParam(required=false) Integer p
){
//...
}
Since you are using primitive int they can't hold the null value. So you can use Wrapper Class Integer. But do remember to use #RequestParam to map GET values to method argument

take the value of enum and covert it to String

I should take from a variable enum its value and transform it to string.how can i do?
here it is the type enum:
public enum State{
b,c,p;
};
now i have to insert into an object String one value.
You might use enum.name orenum.toString to get the name of the enum constant, or enum.ordinal to get the ordinal position.
you can use name() or toString(), so :
State aState = State.c;
String strState = aState.name();
See here the official java reference for more information...
State.b.toString() will return "b". The same goes for the other ones.
Usually,
State state = ...;
String string = state.toString();
should work, but it is not recommended since someone might override toString for some other purpose.
Instead the method you are looking for is
String string = state.name();
As an aside, your enumerated stated should always be all in capitals, and they should have descriptive names. It's not a language rule, but a convention. For example enum State { ON, OFF, PAUSED; }.
I tend to do something more complicated, but I find that it's more flexible:
public enum MyEnumeration {
SOME_NAME("Some Name"),
OTHER_THING("Other Thing"),
...
MORE_VALUES("More Values"),
private final String displayName;
private MyEnumeration(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
}
This way, I use standard capitalization for my enums in code, but can have a more presentable name for them.
This trick can also be used to replace ordinal, by initializing a number, and then you don't need to worry about rearranging your enums.
Method #1: Using the built-in toString() and name() methods
If you want to print a String that is the same as the value of the State, then you can use the toString() method, or the name() method.
System.out.println(State.b); // Prints "b"
System.out.println(State.c); // Prints "c"
System.out.println(State.p); // Prints "p"
Method #2: Using a constructor to create a custom mapping
If you want to have a custom String associated with each of those states, you can use a constructor to associate a particular value with each enum value:
public enum State{
b("State B"), c("State C"), p("State P");
private String longName;
private State(String longName) {
this.longName = longName;
}
#Override
public String toString() {
return this.longName;
}
};
Of course, if you don't want to break the default toString() usage, you can create a different method called getFullName(), for example, to return the custom value.

Categories

Resources