传递带有自定义类型的地图的正确方法是什么? 我在Spring Boot应用程序中有一个用于银行逻辑的jar文件,作为外部引用的jar文件。 我应该在jar文件或spring boot应用程序中的哪里定义密钥反序列化器? 这甚至是正确的方法吗?
@PutMapping(value = "/api/bank/coins")
@ResponseBody
@JsonDeserialize(keyUsing=CoinKeyDeserializer.class)
public Map<Coin, Integer> updateCoins(@RequestBody Map<Coin, Integer> coins)
{
return bank.updateCoins(coins);
}
Postman PUT request contains the JSON below.
{
"Coin [name=QUARTER, value=$0.25]": 100,
"Coin [name=DIME, value=$0.10]": 100,
"Coin [name=NICKEL, value=$0.05]": 100,
"Coin [name=PENNY, value=$0.01]": 100
}
Springboot error:
{
"timestamp": "2018-07-31T14:56:00.050+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Type definition error: [simple type, class com.zimmy.Coin];
nested exception is
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot
find a (Map) Key deserializer for type [simple type, class
com.zimmy.Coin]\n at [Source: (PushbackInputStream); line: 1, column:
1]", "path": "/api/bank/coins"
}
来自外部jar的类: 包com.zimmy;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.Locale;
public class Coin {
private String name;
private BigDecimal value;
private NumberFormat formatter =
NumberFormat.getCurrencyInstance(Locale.US);
public Coin() {
}
public Coin(String name, BigDecimal value) {
this.name = name;
this.value = value.setScale(2, RoundingMode.HALF_UP);;
}
public BigDecimal getValue() {
return value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setValue(BigDecimal value) {
this.value = value;
}
@Override
public String toString() {
return "Coin [name=" + name + ", value=" + formatter.format(value) +
"]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Coin other = (Coin) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
答案 0 :(得分:0)
您的邮递员json应该是这样的
{ {“name” : “quater”, “value” : 0.25} : 10, {“name” : “penny”, “value” : 0.75} : 100}
要与控制器中的请求模型Map<Coin, Integer>
匹配,但发布的邮递员示例与Map<String, Integer>
匹配。
答案 1 :(得分:0)
我遵循了萨吉布的建议。它可以工作,但是我仍然好奇这是否是最好的方法。
SpringBoot Code:
@PutMapping(value = "/api/bank/coins")
@ResponseStatus(HttpStatus.OK)
@ResponseBody
// @JsonDeserialize(keyUsing=CoinKeyDeserializer.class)
public Map<Coin, Integer> updateCoins(@RequestBody Map<String, Integer> coinsString)
{
Map<Coin, Integer> coins = new LinkedHashMap<Coin, Integer>();
System.out.println("RequestBody: "+coinsString);
for (Entry<String, Integer> entry : coinsString.entrySet()) {
String json = entry.getKey();
System.out.println("Coin JSON: "+json);
Coin coin = getCoinFromJSON(json);
coins.put(coin, entry.getValue());
}
return bank.updateCoins(coins);
}
private Coin getCoinFromJSON(String json) {
Coin coin = null;
ObjectMapper mapper = new ObjectMapper();
try {
coin = mapper.readValue(json, Coin.class);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return coin;
}
POSTMAN PUT Request:
{
"{\"name\":\"NINETYC\",\"value\":0.90}":100,
"{\"name\":\"SEVENTYC\",\"value\":0.70}":100,
"{\"name\":\"FIFTYC\",\"value\":0.50}":100,
"{\"name\":\"QUARTER\",\"value\":0.25}":100,
"{\"name\":\"DIME\",\"value\":0.10}":100,
"{\"name\":\"NICKEL\",\"value\":0.05}":100,
"{\"name\":\"PENNY\",\"value\":0.01}":100
}
Springboot Console:
2018-08-04 14:37:03.085 INFO 35760 --- [nio-8081-exec-2]
o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet':
initialization completed in 13 ms
RequestBody: {{"name":"NINETYC","value":0.90}=100,
{"name":"SEVENTYC","value":0.70}=100, {"name":"FIFTYC","value":0.50}=100,
{"name":"QUARTER","value":0.25}=100, {"name":"DIME","value":0.10}=100,
{"name":"NICKEL","value":0.05}=100, {"name":"PENNY","value":0.01}=100}
Coin JSON: {"name":"NINETYC","value":0.90}
Coin JSON: {"name":"SEVENTYC","value":0.70}
Coin JSON: {"name":"FIFTYC","value":0.50}
Coin JSON: {"name":"QUARTER","value":0.25}
Coin JSON: {"name":"DIME","value":0.10}
Coin JSON: {"name":"NICKEL","value":0.05}
Coin JSON: {"name":"PENNY","value":0.01}