1. 程式人生 > >呼叫服務異常Jackson日期轉換異常-Error while extracting response for type...省略...while it seems to fit format

呼叫服務異常Jackson日期轉換異常-Error while extracting response for type...省略...while it seems to fit format

寫自動化單元測試用例的時候出錯, 錯誤資訊:

2018-10-03 20:41:47.099  INFO 10068 --- [           main] com.imooc.util.RestUtil                  : rest-post-json-請求引數:<{"id":"T001","name":"靈活寶1號","status":"AUDITING","thresholdAmount":10,"stepAmount":1,"lockTerm":null,"rewardRate":3.42,"memo":null,"createAt":null,"updateAt":null,"createUser":null,"updateUser":null},{Content-Type=[application/json;charset=UTF-8], Accept=[application/json]}>
2018-10-03 20:41:47.368  INFO 10068 --- [o-auto-1-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-10-03 20:41:47.370  INFO 10068 --- [o-auto-1-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2018-10-03 20:41:47.423  INFO 10068 --- [o-auto-1-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 53 ms
2018-10-03 20:41:47.540  INFO 10068 --- [o-auto-1-exec-2] c.i.m.controller.ProductController       : 增加產品, 引數:
[email protected]
[id=T001,name=靈活寶1號,status=AUDITING,thresholdAmount=10,stepAmount=1,lockTerm=<null>,rewardRate=3.42,memo=<null>,createAt=<null>,updateAt=<null>,createUser=<null>,updateUser=<null>] 2018-10-03 20:41:47.559 INFO 10068 --- [o-auto-1-exec-2] c.imooc.manager.service.ProductService : 建立產品, 引數:
[email protected]
[id=T001,name=靈活寶1號,status=AUDITING,thresholdAmount=10,stepAmount=1,lockTerm=<null>,rewardRate=3.42,memo=<null>,createAt=<null>,updateAt=<null>,createUser=<null>,updateUser=<null>] Hibernate: select product0_.id as id1_1_0_, product0_.create_at as create_a2_1_0_, product0_.create_user as create_u3_1_0_, product0_.lock_term as lock_ter4_1_0_, product0_.memo as memo5_1_0_, product0_.name as name6_1_0_, product0_.reward_rate as reward_r7_1_0_, product0_.status as status8_1_0_, product0_.step_amount as step_amo9_1_0_, product0_.threshold_amount as thresho10_1_0_, product0_.update_at as update_11_1_0_, product0_.update_user as update_12_1_0_ from product product0_ where product0_.id=? Hibernate: insert into product (create_at, create_user, lock_term, memo, name, reward_rate, status, step_amount, threshold_amount, update_at, update_user, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 2018-10-03 20:41:47.814 INFO 10068 --- [o-auto-1-exec-2] c.imooc.manager.service.ProductService : 建立產品, 結果:
[email protected]
[id=T001,name=靈活寶1號,status=AUDITING,thresholdAmount=10,stepAmount=1,lockTerm=0,rewardRate=3.42,memo=<null>,createAt=Wed Oct 03 20:41:47 CST 2018,updateAt=Wed Oct 03 20:41:47 CST 2018,createUser=<null>,updateUser=<null>] 2018-10-03 20:41:47.814 INFO 10068 --- [o-auto-1-exec-2] c.i.m.controller.ProductController : 增加產品, 結果:[email protected][id=T001,name=靈活寶1號,status=AUDITING,thresholdAmount=10,stepAmount=1,lockTerm=0,rewardRate=3.42,memo=<null>,createAt=Wed Oct 03 20:41:47 CST 2018,updateAt=Wed Oct 03 20:41:47 CST 2018,createUser=<null>,updateUser=<null>] 2018-10-03 20:41:47.943 INFO 10068 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test context [[email protected] testClass = ProductControllerTest, testInstance = [email protected], testMethod = [email protected], testException = org.springframework.web.client.RestClientException: Error while extracting response for type [class com.imooc.entity.Product] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)) at [Source: (PushbackInputStream); line: 1, column: 147] (through reference chain: com.imooc.entity.Product["createAt"]), mergedContextConfiguration = [[email protected] testClass = ProductControllerTest, locations = '{}', classes = '{class com.imooc.manager.ManagerApp}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}', contextCustomizers = set[org.springfr[email protected]262b2c86, org.springframework.boot.test.json.DuplicateJsonObje[email protected]50d0686, org.[email protected]0, org.springframework.boot.test.web.c[email protected], org.springframework.boot[email protected]0, org.springframework.boot.test.autocon[email protected]75881071], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> false]]. org.springframework.web.client.RestClientException: Error while extracting response for type [class com.imooc.entity.Product] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)) at [Source: (PushbackInputStream); line: 1, column: 147] (through reference chain: com.imooc.entity.Product["createAt"]) at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:115) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:732) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:686) at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:437) at com.imooc.util.RestUtil.postJSON(RestUtil.java:31) at com.imooc.manager.controller.ProductControllerTest.lambda$create$0(ProductControllerTest.java:59) at java.util.ArrayList.forEach(ArrayList.java:1249) at com.imooc.manager.controller.ProductControllerTest.create(ProductControllerTest.java:58) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73) at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)) at [Source: (PushbackInputStream); line: 1, column: 147] (through reference chain: com.imooc.entity.Product["createAt"]) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:241) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:223) at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:100) ... 38 more Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)) at [Source: (PushbackInputStream); line: 1, column: 147] (through reference chain: com.imooc.entity.Product["createAt"]) at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67) at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1548) at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:910) at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:524) at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:467) at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:195) at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:285) at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:268) at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235) ... 40 more 2018-10-03 20:41:47.963 INFO 10068 --- [ Thread-3] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.ser[email protected]22bac7bc: startup date [Wed Oct 03 20:41:37 CST 2018]; root of context hierarchy 2018-10-03 20:41:47.970 INFO 10068 --- [ Thread-3] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2018-10-03 20:41:47.971 INFO 10068 --- [ Thread-3] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2018-10-03 20:41:47.984 INFO 10068 --- [ Thread-3] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. Process finished with exit code -1

注意這個錯誤資訊:

 Error while extracting response for type [class com.imooc.entity.Product] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2018-10-03 20:41:47": not a valid representation (error: Failed to parse Date value '2018-10-03 20:41:47': Cannot parse date "2018-10-03 20:41:47": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null))

分析如下:

"Error while extracting response for type "拉取響應型別時出錯,  "JSON parse error: Cannot deserialize value of type `java.util.Date`", 很明顯無法解析這個日期型別

我的工具類如下:

 /**
     * 傳送post 請求
     *
     * @param restTemplate
     * @param url
     * @param param
     * @param responseType
     * @param <T>
     * @return
     */
    public static <T> T postJSON(RestTemplate restTemplate, String url, Object param, Class<T> responseType) {
        HttpEntity<String> formEntity = makePostJSONEntiry(param);
        T result = restTemplate.postForObject(url, formEntity, responseType);
        log.info("rest-post-json 響應資訊:{}", JsonUtil.toJson(result));
        return result;
    }

    /**
     * 生成json形式的請求頭
     *
     * @param param
     * @return
     */
    public static HttpEntity<String> makePostJSONEntiry(Object param) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<String> formEntity = new HttpEntity<String>(
                JsonUtil.toJson(param), headers);
        log.info("rest-post-json-請求引數:{}", formEntity.toString());
        return formEntity;
    }

因為jackson在轉換資料的時候預設是 'yyyy-MM-dd'T'HH:mm:ss.SSSZ,這樣的型別,

修改Product實體類, 加上如下註解即可

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Entity
public class Product {

    /** 建立時間 */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createAt;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    /** 更新時間 */
    private Date updateAt;

因為如下原因: 在呼叫postJSON請求方式的時候, 建立的是 yyyy-MM-dd HH:mm:ss 格式的日期,  而用 Product result 接收的時候,經過了我的程式碼中 toJson--> return mapper.writeValueAsString(obj); 轉換了, 所以就變成yyyy-MM-dd'T'HH:mm:ss.SSSZ, 就出錯了

@Test
@Transactional
public void create(){
    normals.forEach(product -> {
        Product result = RestUtil.postJSON(restTemplate,baseUrl + "/products",product,Product.class);
        Assert.notNull(result.getName(),"建立產品失敗");
    });
}