Java CXF JAXRS-如何将日期作为QueryParam传递
我有一个服务定义如下Java CXF JAXRS-如何将日期作为QueryParam传递,java,rest,service,cxf,jax-rs,Java,Rest,Service,Cxf,Jax Rs,我有一个服务定义如下 公共字符串getData(@QueryParam(“日期”)date-date) 我试图从我的客户机(它是jaxrs:CXF的客户机,而不是通用的HTTP客户机或浏览器)向它传递一个java.util.Date 我的服务在HTTP URL中接收日期为2012年3月1日星期四22:33:10。由于CXF无法使用此字符串创建Date对象,因此我的客户端收到404错误。 我尝试在服务端使用ParameterHandler,但仍然无法成功解析它,因为我不希望使用任何特定格式的日期
公共字符串getData(@QueryParam(“日期”)date-date)
我试图从我的客户机(它是jaxrs:CXF的客户机,而不是通用的HTTP客户机或浏览器)向它传递一个java.util.Date
我的服务在HTTP URL中接收日期为2012年3月1日星期四22:33:10。由于CXF无法使用此字符串创建Date
对象,因此我的客户端收到404错误。
我尝试在服务端使用ParameterHandler
,但仍然无法成功解析它,因为我不希望使用任何特定格式的日期
根据,传递日期
应该是开箱即用的,但我似乎无法让基本案例起作用。为了成功地将日期对象从我的客户机传递到服务,我是否需要执行任何操作?谢谢你的帮助
谢谢问题在于JAX-RS规定参数拆分可以通过以下两种方式之一完成:
valueOf(String)
方法Date(String)
构造函数进行拆分,该构造函数无法处理客户端发送的输入格式。您有几个选项可以解决此问题:
选项1 让您的客户在发送日期之前更改日期格式。这是理想的,但可能是最难实现的
选项2 处理疯狂的日期格式。这方面的选择包括: 更改方法签名以接受字符串。尝试从中构造日期对象,如果失败,请使用您自己的自定义SimpleDataFormat类对其进行解析。 定义执行上述逻辑的您自己的参数类。给它一个字符串构造函数或调用逻辑的静态
valueOf(string)
方法。还有一个额外的方法来获取所有事情都说了和做了的日期。
或者,最后,您可以注册日期的参数处理程序。其逻辑与上面提到的其他选项完全相同。请注意,您至少需要使用CXF 2.5.3,以便在参数处理程序尝试默认拆分逻辑之前对其进行评估。
公共类DateHandler实现ParameterHandler{
公共映射fromString(字符串s){
最后日期;
试一试{
date=newdate(dateString);//是的,我知道这是一个不推荐使用的方法
}捕获(例外e){
date=CRAZY\u FORMAT.parse(日期字符串);
}
}
}
正如@Perception
在选项2中建议的那样,您可以处理日期。但您应该使用以下选项:
private Date getDateFromString(String dateString) {
try {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = df.parse(dateString);
return date;
} catch (ParseException e) {
//WebApplicationException ...("Date format should be yyyy-MM-dd'T'HH:mm:ss", Status.BAD_REQUEST);
}
}
您可以从资源内部将其称为
Date date = getDateFromString(dateString);//dateString is query param.
使用自定义DateParam类似乎是最安全的选择。然后,您可以在此基础上创建方法签名,并在valueOf()方法或类构造函数中实现丑陋的转换逻辑。与使用普通字符串相比,它还具有更多的自文档功能非常有用,但在Apache cxf 3.0中,
ParameterHandler
已被弃用,请参见:
已删除CXF JAX-RS ParameterHandler,请使用JAX-RS 2.0 ParamConverterProvider
因此,我添加了一个带有ParamConverterProvider
的示例:
public class DateParameterConverterProvider implements ParamConverterProvider {
@Override
public <T> ParamConverter<T> getConverter(Class<T> type, Type type1, Annotation[] antns) {
if (Date.class.equals(type)) {
@SuppressWarnings("unchecked")
ParamConverter<T> paramConverter = (ParamConverter<T>) new DateParameterConverter();
return paramConverter;
}
return null;
}
}
public class DateParameterConverter implements ParamConverter<Date> {
public static final String format = "yyyy-MM-dd"; // set the format to whatever you need
@Override
public Date fromString(String string) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
try {
return simpleDateFormat.parse(string);
} catch (ParseException ex) {
throw new WebApplicationException(ex);
}
}
@Override
public String toString(Date t) {
return new SimpleDateFormat(format).format(t);
}
}
有关更多信息,请参阅。不确定您所说的
是什么意思导致日期被发送为2012年3月1日星期四22:33:10
,因为您收到的是日期,而不是发送日期。在调用URL之前,请确保您正在调用的URL已正确编码。编辑此帖子以进行澄清。URL已正确编码。我的客户将日期参数作为2012年3月1日星期四22:33:10发送,我的服务也将按原样接收。但是,日期的格式无法解析(如果我使用ParameterHandler),或者CXF无法使用该格式直接创建日期对象。这让事情变得更清楚。这就引出了下一个问题——这种方法是否也能处理其他(更标准)格式的日期?实际上,我根本不关心日期格式。只要我能够传递日期
对象,就足够了,内部使用的格式可以是任何格式。如果有帮助的话,我不介意在内部使用特定的格式(例如yyyyMMddHHmmSS)。实际上,我是为了更好地确定处理传入日期的解决方案而询问的。请看下面我的答案。Reg。选项#1:在这种情况下,我自己将客户机分发给用户,因此如果有帮助,我可以自由选择固定日期格式。但问题是,我到底该怎么做?什么决定了CXF客户端将使用哪种格式?我仍然将java.util.Date
保留为QueryParam
,而不是更改为String
或另一个DateParam
类对象,以封装Date
对象。只需传入任何可以由date(String)
构造函数处理的日期格式。例如“12/20/2005 09:30:00+0100”(mm/dd/yyy HH:mm:ss Z)。我确实可以控制客户,但我在客户和服务端的签名都应该是日期
。由于在客户端,CXF在构造查询参数时在我的Date
对象上内部调用toString()?您是否建议延长Date
并覆盖toString()
(这意味着客户端签名将更改)?或者是否有其他机制可以在客户端和服务端使用来覆盖该行为?我猜MessageBodyReader/Wrtier
仅用于请求正文。我最终使用了ParameterHand
private Date getDateFromString(String dateString) {
try {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = df.parse(dateString);
return date;
} catch (ParseException e) {
//WebApplicationException ...("Date format should be yyyy-MM-dd'T'HH:mm:ss", Status.BAD_REQUEST);
}
}
Date date = getDateFromString(dateString);//dateString is query param.
public class DateParameterConverterProvider implements ParamConverterProvider {
@Override
public <T> ParamConverter<T> getConverter(Class<T> type, Type type1, Annotation[] antns) {
if (Date.class.equals(type)) {
@SuppressWarnings("unchecked")
ParamConverter<T> paramConverter = (ParamConverter<T>) new DateParameterConverter();
return paramConverter;
}
return null;
}
}
public class DateParameterConverter implements ParamConverter<Date> {
public static final String format = "yyyy-MM-dd"; // set the format to whatever you need
@Override
public Date fromString(String string) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
try {
return simpleDateFormat.parse(string);
} catch (ParseException ex) {
throw new WebApplicationException(ex);
}
}
@Override
public String toString(Date t) {
return new SimpleDateFormat(format).format(t);
}
}
<jaxrs:server id="myService" address="/rest">
<jaxrs:serviceBeans>
...
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="dateParameterConverterProvider" />
</jaxrs:providers>
</jaxrs:server>
<bean id="dateParameterConverterProvider" class="myPackage.DateParameterConverterProvider"/>