Reputation: 431
I need to get a token from an external API and keep it cached. I need an api key, email and password.
Naturally I thought that creating an object with all of these elements would be the way to go:
public class LoginObj {
private String apiKey;
private String email;
private String password;
//... sets, gets and constructors
but it doesn't seem to cache in a method like this:
@Cacheable(value = "token")
public String getToken(LoginClass login) {
System.out.println("no cache");
return webClient.post()
.uri("my/uri")
.header("Api-Key", login.getApiKey())
.accept(MediaType.APPLICATION_JSON)
.bodyValue(new LoginClass( login.getEmail() , login.getPassword() ))
.retrieve()
.bodyToMono(JsonNode.class)
.block()
.get("token")
.asText();
}
the "no cache" println keeps showing up, which shows that the method still been called.
The only way that it seems to work is like this:
@Cacheable(value = "token")
public String getToken(String apiKey, String email, String senha) {
System.out.println("no cache");
return webClient.post()
.uri("my/uri")
.header("Api-Key", apiKey)
.accept(MediaType.APPLICATION_JSON)
.bodyValue(new LoginObj(email, senha))
.retrieve()
.bodyToMono(JsonNode.class)
.block()
.get("token")
.asText();
}
Seems like whenever there is an object as a parameter it won't work. Can I pass an object as a parameter or is this a limitation on this case?
Upvotes: 1
Views: 1648
Reputation: 199215
Probably you're not overriding equals
& hashCode()
in LoginObj
For example the following will print "false"
class L {
String s;
public static void main(String ... args) {
var a = new L();
a.s = "should be the same";
var b = new L();
b.s = "should be the same";
System.out.println(a.equals(b));
}
}
It prints false
because despite the fact they contain the same value ("should be the same"
) they're different objects. Think of a person, or a dog, just because they have the same name doesn't mean they're the same.
You have to explicitly define what makes an instance of your class equals to another, in your case you want the three strings to match
class LoginObj {
...
@Override
public boolean equals(Object o) {
return o instanceof LoginObj
&& apiKey.equals((LoginObj)o).apiKey
&& email.equals((LoginObj)o).email
&& password.equals((LoginObj)o).password
}
...
}
You have to override hashCode
as well. See this answer for more details: Why do I need to override the equals and hashCode methods in Java?.
Upvotes: 2