繁体   English   中英

Spring REST API 用于pojo的注册日期转换器

[英]Spring REST API register date converter for pojo

Spring rest 默认从路径变量和 url 参数提供构建 pojo 功能。

就我而言,我有 pojo:

public class MyCriteria {
  private String from;
  private String till;
  private Long communityNumber;
  private String communityName;
}

在我的 controller 中使用。 Url 是http://localhost:8080/community/{communityNumber}/app 请求结果

curl "http://localhost:8080/community/1/app?from=2018-11-14&till=2019-05-13&communityName=myCOm"

是:

{
  'from':'2018-11-14';
  'till':'2019-05-12';
  'communityNumber':'1';
  'communityName':'myCOm'
}

它似乎工作正常。 在 pojo 数据中拥有按目的所需的类型要好得多。 所以我想from till类型的LocalDate 使用 spring 我希望这个解决方案几乎是开箱即用的 但是由于生命周期,任何 spring 或 jackson 日期转换器都无法解决我的问题。

Spring 在注入日期之前验证 pojo 字段的类型,我得到类型不匹配异常。 我认为一般原因是使用 spring 的特殊构建器,它试图按名称查找所需的参数,它忽略了要在 pojo 内部应用的字段的注释。

问题是:

通过 spring 构建 pojo 是否有任何优雅的解决方案,默认情况下某些字段将从String转换为LocalDate格式?

附言

强制性条件是:

  • 请求方法是GET
  • 所需的 pojo 是:
public class MyCriteria {
  private LocalDate from;
  private LocalDate till;
  private Long communityNumber;
  private String communityName;
}
  • 让我们跳过自定义 AOP 实现或注入转换逻辑的getter的想法;
  • 既没有正文(请求正文为空)也没有 json(所有必需的数据都是路径变量或路径参数)。

PS2。

  • 可用于实验的 Controller 示例为:
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import org.vl.example.rest.dtofromoaramsandpath.web.dto.MyCriteria;

import java.time.LocalDate;

@RestController
@RequestMapping("verify/criteria/mapping")
@Slf4j
public class MyController {

    @GetMapping("community/{communityNumber}/dto")
    public MyCriteria loadDataByDto(MyCriteria criteria) {
        log.info("received criteria: {}", criteria);
        return criteria;
    }

    @GetMapping("community/{communityNumber}/default/params")
    public String loadDataByDefaultParameters(@PathVariable("communityNumber") String communityNumber,
                                            @RequestParam(value = "from", required = false) String from,
                                            @RequestParam(value = "till", required = false) String till,
                                            @RequestParam(value = "communityName", required = false) String communityName) {
        log.info("received data without converting:\n\tcommunityNumber => {}\n\tfrom => {}\n\ttill => {}\n\tcommunityName => {}",
                communityNumber, from, till, communityName);
        return new StringBuilder("{")
                .append("\n\tfrom:").append(from).append(";")
                .append("\n\tfrom:").append(from).append(";")
                .append("\n\ttill:").append(till).append(";")
                .append("\n\tcommunityName:").append(communityName)
                .append("\n}\n").toString();
    }

    @GetMapping("community/{communityNumber}/converted/params")
    public String loadUsingConvertedParameters(@PathVariable("communityNumber") String communityNumber,
                                             @RequestParam(value = "from") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from,
                                             @RequestParam("till") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate till,
                                             @RequestParam(value = "communityName", required = false) String communityName) {
        log.info("received data with LocalDate converting:\n\tcommunityNumber => {}\n\tfrom => {}\n\ttill => {}\n\tcommunityName => {}",
                communityNumber, from, till, communityName);
        return new StringBuilder("{")
                .append("\n\tfrom:").append(from).append(";")
                .append("\n\tfrom:").append(from).append(";")
                .append("\n\ttill:").append(till).append(";")
                .append("\n\tcommunityName:").append(communityName)
                .append("\n}\n").toString();
    }
}
  • 链接到 github 项目,该项目包含具有所需controllercriteria的模块,以使您的理解和实验更有用。

这可能会帮助你。 我有类似的情况,我使用这种方法将数据转换为特定要求。

public class MyCriteria {
  public MyCriteria(LocalDate from, LocalDate till, Long communityNumber, String communityName){
   // assignement of variables
}
  private LocalDate from;
  private LocalDate till;
  private Long communityNumber;
  private String communityName;
}

因此,每当您从 JSON 创建 object 时,它都会根据要求创建它。

当我实现这个时,我使用了“Jackson”的 ObjectMapper class 来做这件事。 希望你也一样。

使用 java.sql.Date 里面的 pojo class.like private Date from。 我希望它适用于 JSON 转换。 当您从 UI 接收日期 JSON 字段时,请始终使用 Java.sql.Date for Z7930C25260E609E4A981 convert

为此,您需要添加jsr310依赖项。

compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.10")

我希望这对你有用。

问题的答案是使用 init binder 在指定条件内注册类型映射。 需要为特定目的实现PropertyEditorSupport

短代码示例是:

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(LocalDate.parse(text, DateTimeFormatter.ISO_LOCAL_DATE));
            }
        });
    }

完整的代码示例可以从github 获取

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.vl.example.rest.dtofromoaramsandpath.web.dto.MyCriteriaLd;

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

@RestController
@RequestMapping("verify/criteria/mapping")
@Slf4j
public class MyControllerLd {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(LocalDate.parse(text, DateTimeFormatter.ISO_LOCAL_DATE));
            }
        });
    }

    @GetMapping("community/{communityNumber}/dtold")
    public MyCriteriaLd loadDataByDto(MyCriteriaLd criteria) {
        log.info("received criteria: {}", criteria);
        return criteria;
    }
}

所以这个案例的 model 可以是下一个:

import lombok.Data;

import java.time.LocalDate;

@Data
public class MyCriteriaLd {
    private LocalDate from;
    private LocalDate till;
    private Long communityNumber;
    private String communityName;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM