java - 如何使用转换器?

标签 java spring jsp spring-data-jpa

在我的代码中我想要 t

我使用 LocalDataTime 格式,如下所示:

@Entity
@Table(name="meals")
public class Meal {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column(name = "date_time")
    @Convert(converter = MealConverter.class)
    private LocalDateTime datetime;

    @Column(name = "description")
    private String description;

    @Column(name = "calories")
    private int calories;

    public Meal() {
    }

    public Meal(int id) {
        this.id = id;
    }

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

    public int getId() {
        return id;
    }

    public LocalDateTime getDatetime() {
        return datetime;
    }

    public void setDatetime(LocalDateTime datetime) {
        this.datetime = datetime;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getCalories() {
        return calories;
    }

    public void setCalories(int calories) {
        this.calories = calories;
    }

    public boolean isNew() {
        return this.id == null;
    }
}

在 xml 中我使用它:

    <context:property-placeholder location="classpath:db/postgres.properties"/>

    <bean id="myDataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driverClassName}"/>
        <property name="url" value="${database.url}"/>
        <property name="username" value="${database.username}"/>
        <property name="password" value="${database.password}"/>
    </bean>

    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="packagesToScan" value="ru.demo.exercise.models"/>
        <property name="dataSource" ref="myDataSource"/>

        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</prop>
            </props>
        </property>

        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
        </property>
    </bean>

    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <jpa:repositories base-package="ru.demo.exercise.repository" entity-manager-factory-ref="entityManagerFactory"/>

    <tx:annotation-driven/>
</beans>

日志中的错误:

Field error in object 'mealsCreate' on field 'datetime': rejected value [2020-05-11T11:08]; codes [typeMismatch.mealsCreate.datetime,typeMismatch.datetime,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [mealsCreate.datetime,datetime]; arguments []; default message [datetime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'datetime'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'datetime': no matching editors or conversion strategy found]]

我的转换器:

@Converter(autoApply = true)
public class Converter implements AttributeConverter<Meal, String> {

private static final String SEPARATOR = ", ";

@Override
public String convertToDatabaseColumn(Meal meal) {
    if (meal == null) {
        return null;
    }

    StringBuilder sb = new StringBuilder();
    if (meal.getDatetime() != null) {
        sb.append(meal.getDatetime());
        sb.append(SEPARATOR);
    }

    if (meal.getDescription() != null
            && !meal.getDescription().isEmpty()) {
        sb.append(meal.getDescription());
    }

    return sb.toString();
}

@Override
public Meal convertToEntityAttribute(String dbPersonName) {
    if (dbPersonName == null || dbPersonName.isEmpty()) {
        return null;
    }

    String[] pieces = dbPersonName.split(SEPARATOR);

    if (pieces == null || pieces.length == 0) {
        return null;
    }

    Meal meal = new Meal();
    String firstPiece = !pieces[0].isEmpty() ? pieces[0] : null;
    if (dbPersonName.contains(SEPARATOR)) {
        meal.getDescription();

        if (pieces.length >= 2 && pieces[1] != null
                && !pieces[1].isEmpty()) {
            meal.setDescription(pieces[1]);
        }
    } else {
        meal.setDescription(firstPiece);
    }

    return meal;
}

}

和我的模型:

@Entity
@Table(name="meals")
public class Meal {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column(name = "date_time")
    @Convert(converter = MealConverter.class)
    private LocalDateTime datetime;

    @Column(name = "description")
    private String description;

    @Column(name = "calories")
    private int calories;

    public Meal() {
    }

    public Meal(int id) {
        this.id = id;
    }

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

    public int getId() {
        return id;
    }

    public LocalDateTime getDatetime() {
        return datetime;
    }

    public void setDatetime(LocalDateTime datetime) {
        this.datetime = datetime;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getCalories() {
        return calories;
    }

    public void setCalories(int calories) {
        this.calories = calories;
    }

}

我的jsp表单:

<html>
<head>
    <title></title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>

<div class="container">
    <h2><a href="${pageContext.request.contextPath}/list">Home</a></h2>
    <h2 align="center"></h2>

    <div id="row">
        <%--@elvariable id="mealsCreate" type=""--%>
        <form:form action="${pageContext.request.contextPath}/create"
                   modelAttribute="mealsCreate" method="post">
            <div class="col-md-9">
                <input type="hidden"/>

                <div class="form-group">
                    <div class="col-md-12">
                        <label for="dateTime">DateTime</label>
                        <input id="dateTime" type="datetime-local" name="datetime"/>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-12">
                        <label for="description" type="table" class="table">Description</label>
                        <input id="description" type="text" name="description"/>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-12">
                        <label for="calories" type="table" class="table">Calories</label>
                        <input id="calories" type="number" name="calories"/>
                    </div>
                </div>

                <button type="submit" class="btn btn-default" name="saveMeals">Save</button>
                <button type="button" class="btn btn-default" name="cancelMeals" onclick="window.history.back()">
                    Cancel
                </button>

            </div>
        </form:form>
    </div>
</div>
</body>

我的代码有什么问题?

最佳答案

您需要根据属性类型而不是模型的类型来实现转换器。在您的情况下,LocalDateTime:

@Converter(autoApply = true)
public class LocalDateTimeConverter implements AttributeConverter<LocalDateTime, String> {

    @Override
    public String convertToDatabaseColumn(LocalDateTime localDateTime) {
        // code to convert from localDateTime to String
    }

    @Override
    public Meal convertToEntityAttribute(String stringDateTime) {
        // code to convert from  String to localDateTime
    }
}

然后您需要将此转换器应用于该属性:

public class Meal {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column(name = "date_time")
    @Convert(converter = LocalDateTimeConverte.class)
    private LocalDateTime datetime;
    //(...)
}

关于java - 如何使用转换器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60888392/

相关文章:

java - 帕斯卡三角算法 JAVA JSP

java - 使用哪种 JVM 脚本语言来定制 Java Web 应用程序?

java - Bazel构建错误 "No such file or directory"

java - 模型中的必填字段

java - 如何在不显式使用构造函数的情况下生成不可变的 DTO?

Spring Boot @RestController,发现不明确的映射

java - Hibernate:删除的对象将通过级联重新保存

spring - 如何在Spring-ws中定位生成的wsdl的路径

jquery - 在调整大小和选项卡 View 期间,图像点击功能不起作用

java - 在java中集成ms access和mysql