Aru*_*mar 7 datetime cxf java-8
我的Web应用程序使用Apache CXF和JAVA8,并且如果用户将xs:datetime输入(秒00)发送为,则响应以下错误
<urn1:dateTimeVal>2016-04-29T20:00:00</urn1:dateTimeVal>
Run Code Online (Sandbox Code Playgroud)
错误:
org.apache.cxf.interceptor.Fault:编组错误:cvc-datatype-valid.1.2.1:'2016-04-29T20:00'不是'dateTime'的有效值。
我进行了调试和分析,如果用户发送dateTimeValas,2016-04-29T20:00:00则传递输入的CXF验证并将XML值取消编组为java.time.LocalDateTimeas 2016-05-05T20:00,并且在返回响应时,由于秒损失part(00)而发生了编组错误。
任何帮助/提示表示赞赏。
PS:您可以尝试以下代码段:
java.time.LocalDateTime dt= java.time.LocalDateTime.of(2016, Month.MAY, 5, 20, 00, 00);
System.out.println(dt);
Run Code Online (Sandbox Code Playgroud)
注意:上面的代码示例仅用于理解打印日期时间值。但是,Web应用程序中期望的实际返回类型是java.time.LocalDateTime
预期输出:2016-05-05T20:00:00
实际产量 :2016-05-05T20:00
编辑:该字段的绑定(JAXB)内容是:
@XmlElement(required = true, type = String.class)
@XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
@XmlSchemaType(name = "dateTime")
@Generated(value = "com.sun.tools.xjc.Driver", date = "2016-05-03T05:28:57+05:30", comments = "JAXB RI v2.2.11")
@NotNull
protected LocalDateTime dateTimeVal;
Run Code Online (Sandbox Code Playgroud)
AND LocalDateTimeAdapter文件为
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class LocalDateTimeAdapter
extends XmlAdapter<String, LocalDateTime>
{
public static LocalDateTime parse(String value)
{
DateTimeFormatter dateTimeAndZoneformatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
DateTimeFormatter dateTimeformatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
TemporalAccessor ta = null;
try
{
ta = dateTimeformatter.parse(value);
}
catch (DateTimeParseException ex)
{
ta = dateTimeAndZoneformatter.parse(value);
}
return LocalDateTime.from(ta);
}
public static String print(LocalDateTime value)
{
return value.toString();
}
public LocalDateTime unmarshal(String value)
{
return parse(value);
}
public String marshal(LocalDateTime value)
{
return print(value);
}
}
Run Code Online (Sandbox Code Playgroud)
问题似乎出在LocalDateTimeAdapter.print(). LocalDateTime.toString()当秒值为 0 时省略秒。
如果你把它改成
public static String print(LocalDateTime value)
{
return value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
Run Code Online (Sandbox Code Playgroud)
它还将在编组时提供秒数。
要查看快速示例,请注意以下代码段的结果:
System.out.println(LocalDateTime.of(2016,1,1,0,0,0,0).toString());
System.out.println(LocalDateTime.of(2016,1,1,0,0,0,0).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
Run Code Online (Sandbox Code Playgroud)
它给出的输出是
2016-01-01T00:00
2016-01-01T00:00:00
Run Code Online (Sandbox Code Playgroud)
在LocalDateTime.toString()它的文档中解释了这种行为:
输出将是以下 ISO-8601 格式之一:
- uuuu-MM-dd'T'HH:mm
- uuuu-MM-dd'T'HH:mm:ss
- uuuu-MM-dd'T'HH: mm:ss.SSS
- uuuu-MM-dd'T'HH:mm:ss.SSSSSS
- uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSS
使用的格式将是输出完整值的最短格式省略部分隐含为零的时间。
您可能想使用
System.out.println (DateTimeFormatter.ISO_LOCAL_DATE_TIME.format (dt));
Run Code Online (Sandbox Code Playgroud)
它给:
2016-05-05T20:00:00
Run Code Online (Sandbox Code Playgroud)