2014-06-07 58 views
1

我必須將傳入的參數值轉換爲需要的格式的Repository接口,是否可以這樣做。我的域類,如何在Spring Data Rest中格式化@param字符串

@DynamoDBTable(tableName = "test") 
public class Test implements Serializable{ 

    @Id 
    private String id; 
    private String name; 
    private String date; 

    @DynamoDBHashKey(attributeName = "id") 
    @DynamoDBAutoGeneratedKey 
    public String getId() { 
     return id; 
    } 

    @DynamoDBAttribute(attributeName = "name") 
    public String getName() { 
     return name; 
    } 

    @DynamoDBAttribute(attributeName = "date") 
    @JsonSerialize(using = StringDateSerializer.class) 
    public String getDate() { 
     return date; 
    } 
    public void setId(String id) { 
     this.id = id; 
    } 

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

    @JsonDeserialize(using = StringDateDeserializer.class) 
    public void setDate(String date) { 
     this.date = date; 
    } 

} 

我的倉庫接口,

@EnableScan 
@RestResource(path="test", rel="test") 
public interface TestRepository extends PagingAndSortingRepository<Test, String>{ 

    @RestResource(path="testsearch", rel="test") 
    public Page<Test> findByNameAndDateLessThan(@Param("name") String name, @Param("date") String date, Pageable pageable); 

} 

這裏我使用的getTime的Java()方法將傳入的日期字符串轉換爲時間。是否有可能在不使用控制器的情況下實現此目的,並且由於可能會發生時區問題,所以對客戶端發送不感興趣。

我的轉換器:

public class StringDateSerializer extends JsonSerializer<String> { 

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); 

    @Override 
    public void serialize(String time, JsonGenerator gen, 
      SerializerProvider provider) throws IOException, 
      JsonProcessingException { 
     Date date = new Date(Long.parseLong(time)); 
     String formattedDate = dateFormat.format(date); 
     gen.writeString(formattedDate); 
    } 

} 

public class StringDateDeserializer extends JsonDeserializer<String> { 

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); 

    @Override 
    public String deserialize(JsonParser parser, DeserializationContext context) 
      throws IOException, JsonProcessingException { 
     String dateReceived = parser.getText(); 
     Date date = null; 
     try { 
      date = dateFormat.parse(dateReceived); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 
     return String.valueOf(date.getTime()); 
    } 

} 

這裏我使用,GET /測試/搜索/測試名稱= XX &日期= 14-06-2014?我需要獲取日期小於14-06-2014的所有名稱,並在14-06-2014之後或之後保留數據。

雖然POST和GET,我已經使用JsonSerialize和JsonDeserialize註釋轉換傳入和傳出的字符串,但如果我想使用查找器方法獲取任何數據,它不會轉換,因爲我認爲。例如,如果我保存{「name」:「Test」,「date」:「08-10-2014」},那麼在數據庫中它將被保存等價時間,如果我想使用它搜索它08-10-2014不是時間常數。我是新來的泉水,我無法找到一個方法。提前致謝。

+0

我有沒有正確理解,你不能查詢日期字符串「08-10-2014」,而你有一個記錄{「名稱」:「測試」,「日期」:「08-10-2014」}在你的DynamoDB? – mavarazy

+0

@mavarazy - >不,我只會將它保存爲字符串。所以我可以查詢它。其實我會把它作爲字符串,並使用這個** String.valueOf(date.getTime())**,我將它保存到數據庫,即使我們保存爲08-06-2014也我們可以搜索它,因爲我們是將其保存爲字符串。但是我們不能像這些操作那樣執行LessThan或GreaterThan。所以我更願意將它保存爲時間,而我使用** GET/test/search/testsearch **我將傳遞參數**?name = test && date = 08-01-2014 **和存儲庫中** @Param * *用於讀取數據,必須使用轉換器從08-01-2014轉換爲等效時間 – jAddict

+0

如果您希望能夠按日期查詢,請查看http://stackoverflow.com/questions/14836600/querying -dynamodb-dy-date,雖然,據我所知GSI還沒有被spring-data-dynamodb支持,你可以在github中做適當的請求。 – mavarazy

回答

8

您在第一位使用String作爲日期類型的原因是什麼?這是非常不理想的(用禮貌的話來說)API設計。

Spring Data REST支持在查詢方法參數上使用@DateTimeFormat將您從HTTP請求獲得的String基本表示形式轉換爲Date。所以,你的資料庫界面可能是這個樣子:

public interface TestRepository extends PagingAndSortingRepository<Test, String>{ 

    public Page<Test> findByNameAndDate(@Param("name") String name, 
    @Param("date") @DateTimeFormat(iso = ISO.DATE) Date date, Pageable pageable); 
} 

這將導致String就像2014-06-08要變成相應的Date

+0

謝謝奧利弗。其實我需要在這裏** findByNameAndDateLessThan **。如果我這樣做,比如它會比較直到2014年,並給出結果並且無法比較整個日期。所以這個想法很長,而且比較容易。如果錯了,請給我建議。 – jAddict

+0

我使用spring數據dynamodb,並且無法使用** DateTimeFormat(iso = ISO.DATE)**作爲參數來使用和轉換日期。每當我作爲參數傳遞時,都會得到這個異常。 ** { cause:null message:「在不支持的null屬性值上創建條件:請爲'date'指定一個值」 } **。但是已經通過了日期參數,並且如果通過日期爲** 2014-06-12T00:00:00.000Z **這種格式,則不會出現異常,但是空對象返回2014-06-12的記錄。它是一個dynamoDB保存問題,我認爲是這樣。 – jAddict

+0

有沒有機會將完整的堆棧跟蹤添加到問題中,並將接口聲明更新爲您當前在代碼庫中的內容? –

0

如果我正確理解你的問題,有兩個方面值得關注--Spring-Data-Rest如何處理日期映射,以及Spring-Data-DynamoDB如何處理日期映射。

關於Spring的數據DynamoDB:

DynamoDB保存日期,絃樂,所以如果你有一個日期屬性作爲你的約會模式的一部分,你可以在你的數據模型來表示他們的字符串(如我認爲你現在在做),或者你可以將它們表示爲日期,並配置Spring-Data-DynamoDB,以便它將日期映射到字符串。這可以使用amazon-aws-sdk中的自定義Marshalers完成,並且已經添加了支持以在Spring Data DynamoDB模塊中處理此問題。

你可以閱讀marshallers這裏:http://java.awsblog.com/post/Tx1K7U34AOZBLJ2/Using-Custom-Marshallers-to-Store-Complex-Objects-in-Amazon-DynamoDB

注意,這編組是,你可能會需要Spring的數據,其餘部分由JSON對象執行任何映射單獨 - 對於這一點,你仍然需要@ DateTimeFormat註釋。

如果您想在數據模型中將日期表示爲java.util.Date,只需使用@DynamoDBMarshalling爲域類中的屬性註釋getter並傳入您希望使用的編組類的類,例如:這裏

@DynamoDBRangeKey(attributeName = "ReplyDateTime") 
@DynamoDBMarshalling(marshallerClass=DefaultDynamoDBDateMarshaller.class) 
public Date getReplyDateTime() { 
... 

DefaultDynamoDBDateMarshaller是從Spring數據DynamoDB的輔助類,但你可以實現自己的自定義日期/串映射。

有了這個地方,現在你可以改變你的資料庫查找方法,所以他們期望日期參數,而不是字符串:

public Page<Reply> findByReplyDateTimeAfter(Date replyDateTime,Pageable pageable); 

希望這有助於

乾杯,

邁克爾

+0

謝謝邁克爾。如果我包含範圍鍵,會得到一個異常**造成者: org.springframework.beans.factory.BeanCreationException:創建名爲'testRepository'的bean時出錯:init方法調用失敗;嵌套異常是java.lang.IllegalArgumentException:類型java.lang.String中沒有由DynamoDBHashKey註釋的方法!**和** java.lang.IllegalArgumentException:類型java.lang.String中沒有由DynamoDBHashKey註釋的方法! ** – jAddict