По-прежнему получаю неверный запрос при передаче данных JSON в контроллер Spring

Я нашел много ответов на одни и те же вопросы, но до сих пор ни один из них не работает для меня :( и я уже устал от недопонимания с моей стороны. Проблема ясна: я передаю строку JSON контроллеру Spring через @RequestBody и получаю "400 Плохой запрос ». Когда я использую @ModelAttribute - все работает, но все значения равны нулю.

Я использую POSTman для отправки запросов. Вот код:

Контроллер:

@RequestMapping(value = "/create", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public @ResponseBody User createUser(@RequestBody User user) {
logger.info("UserController -> createUser call made");
    if (user != null) {
        logger.info("UserController -> createUser(" + user.toString() + ")");
    } else {
        logger.info("UserController -> createUser(null)");
    }
    user.setCreatedDate(new Date());
    return userService.createUser(user);
}

Класс объекта:

@Entity
@Table(name = "users")
@XmlRootElement
public class User implements Serializable {

@Id
@GeneratedValue
private int id;

private String firstName;

private String lastName;

@Transient
private String name;

private String email;

/*
 * 1 - male
 * 0 - female
 */
private boolean gender;

private Date createdDate;

@JsonSerialize(using = DateSerializer.class)
public Date getCreatedDate() {
    return createdDate;
}

public void setCreatedDate(Date createdDate) {
    this.createdDate = createdDate;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public boolean getGender() {
    return gender;
}

public void setGender(boolean gender) {
    this.gender = gender;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public String toString() {
    return getFirstName() + " " +
           getLastName() + ", " +
           (getGender() ? "male, " : "female, ") +
           getEmail() + ", id = " + getId() +
           " created on: [" + getCreatedDate() + "]";
}

JSON передан:

{"gender":true,"lastName":"Novosad","firstName":"Oleg","createdDate":"Sat Sep 20 16:16:48 EEST 2014","email":"[email protected]"}

Headers: Content-Type:application/json

Конфигурация:

<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="text/xml" />
        </map>
    </property>
    <property name="defaultContentType" value="text/html" />
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
        </list>
    </property>
</bean>

Пожалуйста, дайте мне знать, если вам понадобится другая информация. Ценю ваши ответы!

ОБНОВЛЕНИЕ:

После превращения журналов для spring в значение «All» (в log4j.properties укажите строку: log4j.category.org.springframework = ALL) я обнаружил проблему: Spring не может проанализировать значение даты, которое я хотел, чтобы он проанализировал.


person Array    schedule 20.09.2014    source источник
comment
Если вы включите журналы Spring для отладки, Spring сообщит вам, что не так.   -  person Sotirios Delimanolis    schedule 20.09.2014
comment
Установка log4j.category.org.springframework = ALL очень полезна для меня, спасибо.   -  person Paul    schedule 15.04.2016


Ответы (1)


Кажется, вы получаете 400, потому что ваш MappingJackson2HttpMessageConverter и его ObjectMapper не могут десериализовать указанную вами дату.

Самое простое решение - предоставить настраиваемый десериализатор даты, который использует ваш формат даты.

class CustomDateDeserializer extends JsonDeserializer<Date> {

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy");
        try {
            return format.parse(jp.getText());
        } catch (ParseException e) {
            throw new RuntimeException(e); // or handle any other way you like
        }
    }
}

с участием

@JsonSerialize(using = DateSerializer.class)
@JsonDeserialize(using = CustomDateDeserializer.class)
public Date getCreatedDate() {
    return createdDate;
}
person Sotirios Delimanolis    schedule 20.09.2014