Momenteel gebruik ik Jackson om JSON-resultaten uit mijn opspring op basis van websoorten te verzenden.
Het probleem dat ik heb geprobeerd om alle geldvelden te krijgen om met 2 decimalen te worden uitgevoerd. Ik kon dit probleem niet oplossen met setScale(2)
, omdat cijfers zoals 25.50 zijn afgekapt tot 25.5 enz.
Heeft iemand anders dit probleem behandeld? Ik dacht erover om een geldklasse te maken met een Custom Jackson Serializer … kun je een aangepaste serializer maken voor een veldvariabele? Je kunt waarschijnlijk … maar zelfs nog steeds, hoe kan ik mijn klant serializer krijgen om het nummer toe te voegen als een nummer met 2 decimalen?
Antwoord 1, Autoriteit 100%
U kunt een aangepaste serializer gebruiken op uw geldveld. Hier is een voorbeeld met een geldbean. Het veld bedrag wordt geannoteerd met @JSONSIERIZE (met = …) .
public class MoneyBean {
//...
@JsonProperty("amountOfMoney")
@JsonSerialize(using = MoneySerializer.class)
private BigDecimal amount;
//getters/setters...
}
public class MoneySerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonProcessingException {
// put your desired money style here
jgen.writeString(value.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
}
}
Dat is het. Een bigdecimal is nu op de juiste manier afgedrukt. Ik heb een eenvoudige testcase gebruikt om het te laten zien:
@Test
public void jsonSerializationTest() throws Exception {
MoneyBean m = new MoneyBean();
m.setAmount(new BigDecimal("20.3"));
ObjectMapper mapper = new ObjectMapper();
assertEquals("{\"amountOfMoney\":\"20.30\"}", mapper.writeValueAsString(m));
}
Antwoord 2, Autoriteit 51%
U kunt @JsonFormat
annotatie gebruiken met shape
als STRING
op uw BigDecimal
variabelen. Hieronder verwijzen:
import com.fasterxml.jackson.annotation.JsonFormat;
class YourObjectClass {
@JsonFormat(shape=JsonFormat.Shape.STRING)
private BigDecimal yourVariable;
}
Antwoord 3, Autoriteit 43%
In plaats van het instellen van de @JSONSERIALIZE op elk lid of Getter, kunt u een module configureren die een custome serializer gebruikt voor een bepaald type:
SimpleModule module = new SimpleModule();
module.addSerializer(BigInteger.class, new ToStringSerializer());
objectMapper.registerModule(module);
In het bovenstaande voorbeeld gebruikte ik de to String Serializer om Bigintegers te serialiseren (omdat Javascript dergelijke numerieke waarden niet aankan).
Antwoord 4, Autoriteit 18%
Ik ben een van de onderhouders van jackson-datatype-geld , dus neem Dit antwoord met een korrel zout, want ik ben zeker bevooroordeeld. De module moet betrekking hebben op uw behoeften en het is behoorlijk lichtgewicht (geen extra runtime-afhankelijkheden). Daarnaast wordt het vermeld in de jackson docs , Spring Docs en er waren zelfs Sommige discussies al over hoe het te integreren in het officiële ecosysteem van Jackson.
Antwoord 5, Autoriteit 6%
Ik had hetzelfde probleem en ik had het in plaats daarvan in JSON geformatteerd. Kan een beetje een hack zijn, maar het is gemakkelijk te implementeren.
private BigDecimal myValue = new BigDecimal("25.50");
...
public String getMyValue() {
return myValue.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
}
Antwoord 6, autoriteit 2%
Zoals Sahil Chhabrasuggereerde dat je @JsonFormat
met de juiste shape
op uw variabele.
Als je het wilt toepassen op elk BigDecimal
-veld dat je in je Dto's
hebt, kun je de standaardnotatie voor een bepaalde klasse overschrijven.
@Configuration
public class JacksonObjectMapperConfiguration {
@Autowired
public void customize(ObjectMapper objectMapper) {
objectMapper
.configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING));
}
}
Antwoord 7
Geïnspireerd door Steve, en als de updates voor Java 11. Dit is hoe we de BigDecimal-heropmaak hebben gedaan om wetenschappelijke notatie te vermijden .
public class PriceSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// Using writNumber and removing toString make sure the output is number but not String.
jgen.writeNumber(value.setScale(2, RoundingMode.HALF_UP));
}
}