簡體   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