Umarshalling MonthDay spring jackson json

前端 未结 2 2038
醉梦人生
醉梦人生 2021-01-27 18:17

Trying to make a restful service to save \" PeriodeEnseignement \" as below:

package DomainModel.Enseignement.Notations;

import java.time.MonthDay;

import java         


        
相关标签:
2条回答
  • 2021-01-27 18:59

    When you are working with Java 8 Time package and Jackson register JavaTimeModule in your ObjectMapper:

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    

    In Spring you can customise it as below:

    @Bean
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.modules(new JavaTimeModule());
    
        return builder;
    }
    

    EDIT
    Update your method signature to:

    public GenericResponse registerPeriodeEnseignement(@RequestBody PeriodeEnseignement periodeEnseignement)
    

    Use @RequestBody annotation and make method public.

    0 讨论(0)
  • 2021-01-27 19:05

    I finally solved the problem with several modifications.

    1- Changing client-side call from jQuery.post to $.ajax call as shown here

    var form = $('#myForm');
    var jsonFormData = getFormData(form);
    
    $.ajax({
                url : "/path/to/web/service/controller",
                type : "POST",
                dataType : "json",
                contentType : "application/json",
                data : JSON.stringify(jsonFormData),
    
                complete : function() {
                },
    
                success : function(data) {
                    alert("success !");
                },
    
                error : function() {
                    alert("failed !");
                },
            });
        });
    
    function getFormData($form) {
        var unindexed_array = $form.serializeArray();
        var indexed_array = {};
    
        $.map(unindexed_array, function(n, i) {
            indexed_array[n['name']] = n['value'];
        });
    
        return indexed_array;
    }
    

    2- Added @RequestBody to my service-side routine:

    @RequestMapping(value = "/periodeEnseignementService/registerPeriodeEnseignementService", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
    public GenericResponse registerPeriodeEnseignement(@RequestBody PeriodeEnseignement periodeEnseignement) {
        return this.insertNewUniteeEnseignement(periodeEnseignement, this.periodeEnseignementRepository);
    }
    

    3- No need for @DateTimeFormatter neither @JsonFormat("dd/MMM") in the POJO class.

    4- Had to configure a JsonSerializer and a JsonDeserializer for java.time.MonthDay, otherwise, the fields were left null.

    @Bean
        public ObjectMapper objectMapperBuilder() {
            SimpleModule msJavaTimeModule = new SimpleModule();
    
            msJavaTimeModule.addSerializer(MonthDay.class, new JsonSerializer<MonthDay>() {
                @Override
                public void serialize(MonthDay value, JsonGenerator gen, SerializerProvider serializers)
                        throws IOException {
                    gen.writeStartObject();
                    gen.writeStringField("label", value.format(DateTimeFormatter.ofPattern("dd MMM", Locale.FRANCE)));
                    gen.writeEndObject();
                }
            });
    
            msJavaTimeModule.addDeserializer(MonthDay.class, new JsonDeserializer<MonthDay>() {
    
                @Override
                public MonthDay deserialize(JsonParser p, DeserializationContext ctxt)
                        throws IOException, JsonProcessingException {
                    JsonNode node = p.getCodec().readTree(p);
    
                    String content = node.asText();
    
                    int slashIndex = content.indexOf('/');
    
                    String dayAsString = content.substring(0, slashIndex);
                    String monthAsString = content.substring(slashIndex + 1);
    
                    int day = Integer.parseInt(dayAsString);
                    int month = Integer.parseInt(monthAsString);
    
                    return MonthDay.of(month, day);
                }
            });
    
            ObjectMapper objectMapper = new Jackson2ObjectMapperBuilder().modules(msJavaTimeModule).build();
    
            return objectMapper;
        }
    

    Thanks to Michał Ziober for the guidance !

    0 讨论(0)
提交回复
热议问题