为什么每次都记录 DOB 日志,无论是否在 Java 中的更新 API 期间更新?

Why DOB logging every time whether updated or not during update API in Java?

提问人:dracile 提问时间:8/28/2023 最后编辑:Brian Tompsett - 汤莱恩dracile 更新时间:9/1/2023 访问量:66

问:

我正在记录将在更新 API 调用期间更新的字段。 但是每次都获取 DOB 字段,无论它是否正在更新

出生日期类型为

private Date DOB;

在有效负载中传递此值时记录 DOB VALUE{ "DOB": "1990-01-01"}

dob: Mon Jan 01 05:30:00 IST 1990
Updated Fields during request: DOB  

是因为它也有时间吗?尽管我在每个请求上都获得了相同的时间,但即使值相同且未更新,它仍然会打印 DOB 更新。为什么会这样?

如果我像这样在有效载荷(邮递员)中传递 DOB:

 "DOB": "20101212"

//it is printing only this 1970 value on log console
dob: Thu Jan 01 11:05:01 IST 1970 

我该如何处理这些情况?

法典

public static class Updater {
  private final OrgEmployeeMap existing;
  private final EmployeeInformation information;
  private final Set<String> updatedFields = new HashSet<>();

  public Updater(OrgEmployeeMap existing, EmployeeInformation information) {
    this.existing = existing;
    this.information = information;
  }

  public <T> Updater update(String fieldName,
                            Function<EmployeeInformation, T> newValueGetter,
                            Function<OrgEmployeeMap, T> oldValueGetter,
                            BiConsumer<OrgEmployeeMap, T> oldValueSetter) {
    final var newValue = newValueGetter.apply(information);
    final var oldValue = oldValueGetter.apply(existing);
    if (newValue == null || newValue.equals(oldValue)) {
      return this;
    }
    this.updatedFields.add(fieldName);
    oldValueSetter.accept(existing, newValue);
    return this;
  }

  public Set<String> getUpdatedFields() {
    return updatedFields;
  }
}
private void updateExistingEmployee(OrgEmployeeMap existingOrgEmployee, RequestMessage requestMessage) {
    try {
        EmployeeInformation employeeInfo = requestMessage.getData().get(0).getDemographicData().getEmployeeInformation().get(0);
        final var updater = new Updater(existingOrgEmployee, employeeInfo);

        updater
            .update("FirstName", EmployeeInformation::getEmployeeFirstName, OrgEmployeeMap::getFirstName, OrgEmployeeMap::setFirstName)
            .update("LastName", EmployeeInformation::getEmployeeLastName, OrgEmployeeMap::getLastName, OrgEmployeeMap::setLastName)
            .update("DOB", EmployeeInformation::getDOB, OrgEmployeeMap::getDob, OrgEmployeeMap::setDob)
            .update("Gender", EmployeeInformation::getGender, OrgEmployeeMap::getGender, OrgEmployeeMap::setGender)
            .update("Email", EmployeeInformation::getEmail, OrgEmployeeMap::getEmail, OrgEmployeeMap::setEmail);

        final var modifiedFields = updater.getUpdatedFields();
        if (!modifiedFields.isEmpty()) {
            log.info("Updated employee : " + String.join(", ", modifiedFields));
        }

        orgEmployeeMapRepository.save(existingOrgEmployee);

        log.info("Updated Employee : " + existingOrgEmployee);
    } catch (JSONException e) {
        log.error("error in processing the request error", e.getMessage());
    } catch (Exception ex) {
        log.error("An unexpected error occurred: " + ex.getMessage(), ex);
    }
}

DTO 类

@Data
public class EmployeeInformation {

    @JsonProperty(value = "Email")
    private String Email;

    @JsonProperty(value = "EmployeeFirstName")
    private String EmployeeFirstName;

    @JsonProperty(value = "EmployeeLastName")
    private String EmployeeLastName;

    @JsonProperty(value = "DOB")
    private Date DOB;

..
}

Model 类

@Data
@Entity
@Table(name = "employee")
public class EmployeeMap {
@Id
    @Column(name = "Id", length = 100, nullable = false)
    private String Id;

    @Column(name = "firstName", length = 100, nullable = false)
    private String firstName;

    @Column(name = "lastName", length = 100)
    private String lastName;

    @Column(name = "email", length = 100, nullable = false)
    private String email;

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

    @Column(name = "dob", nullable = false)
    private Date dob;
}
Java JSON spring-boot 日期解析

评论

0赞 Arfur Narf 8/28/2023
你如何期望任何人调试你懒得发布的代码?
0赞 dracile 8/28/2023
@ArfurNarf更新了代码,虽然我猜代码工作正常,但日期数据类型存在一些问题,仍然不确定如何处理这个问题。
2赞 Arvind Kumar Avinash 8/28/2023
我建议你停止使用并切换到 API。java.util.Datejava.time
0赞 dracile 8/28/2023
@ArvindKumarAvinash是的,我尝试过并且它对我有用,这属于,谢谢,但它对日期格式有限制,并且我从有效负载发出的请求是以这种格式进行的LocalDate DataTypejava.timeyyyy-mm-ddyyyymmdd
0赞 Bohemian 8/29/2023
您永远不应该记录 DOB。或任何 PII

答:

0赞 queeg 8/28/2023 #1

我会把重点放在线条上

if (newValue == null || newValue.equals(oldValue)) {
  return this;
}
this.updatedFields.add(fieldName);

出于某种原因,每次都为 dob 调用 updatedField.add(...)。 因此,newValue 为 null 或等于 newValue 可能发生的情况不会按预期工作。应用调试会话或添加更多日志输出,以便了解比较失败的原因。

评论

0赞 Bohemian 8/29/2023
或者更简单地说if (Objects.equals(newValue, oldValue))
1赞 Arvind Kumar Avinash 8/28/2023 #2

java.time

日期时间 API 及其相应的解析/格式化类型已过时且容易出错。2014 年 3 月,新式日期时间 API 取代了旧版日期时间 API。从那时起,强烈建议切换到 ,即现代日期时间 API。java.utilSimpleDateFormatjava.time

您可以使用 DateTimeFormatter#BASIC_ISO_DATE(对应于 yyyyMMdd 模式)来解析日期字符串,20101212 .LocalDate

演示:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

class Main {
    public static void main(String[] args) {
        System.out.println(LocalDate.parse("20101212", DateTimeFormatter.BASIC_ISO_DATE));
    }
}

输出:

2010-12-12

根据此说明,可以在代码中进行以下更改:

@JsonProperty(value = "DOB")
@JsonFormat(pattern = "yyyyMMdd", shape = JsonFormat.Shape.STRING)
private LocalDate DOB;

从 Trail 了解新式日期时间 API:日期时间