写自动化单元测试用例的时候出错, 错误信息:
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 : 增加产品, 参数:com.imooc.entity.Product@db6d71b[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 : 创建产品, 参数:com.imooc.entity.Product@db6d71b[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 : 创建产品, 结果:com.imooc.entity.Product@587f46ea[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 : 增加产品, 结果:com.imooc.entity.Product@587f46ea[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 [DefaultTestContext@139982de testClass = ProductControllerTest, testInstance = com.imooc.manager.controller.ProductControllerTest@6f15d60e, testMethod = create@ProductControllerTest, 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 = [WebMergedContextConfiguration@682b2fa 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.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@262b2c86, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@50d0686, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@b7dd107, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@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.servlet.context.AnnotationConfigServletWebServerApplicationContext@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(),"创建产品失败"); }); }