我有一个.net Webservice,它应该通过json与Java应用程序通信。
现在我在服务器端有一个方法如下:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public DateTime GetDate(DateTime input)
{
return input;
}
从C#应用程序我可以发送一个接收DateTime值。惯例是将Date值序列化为:
\/Date(1279176056000)\/
其中数字定义为自纪元以来的秒数。 因此,如果我想调用该服务,我的json请求字符串必须如下所示:
{"input":"\/Date(1279176056000)\/"}
但是,我不知道如何使用Java端的json.org。*类来实现这一点。
问题:如果我使用此代码:
JSONObject json = new JSONObject();
json.put("input", "\\/Date(1279176056000)\\/");
JSONObject足够聪明,可以在通过网络发送之前转义字符串本身,所以我得到:
{"input":"\\/Date(1279176056000)\\/"}
在服务器端反序列化期间导致异常:
System.FormatException: \/Date(1279183256000)\/ is not a valid value for DateTime
bei System.ComponentModel.DateTimeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
bei System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)
bei System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)
bei System.Web.Script.Serialization.ObjectConverter.ConvertObjectToType(Object o, Type type, JavaScriptSerializer serializer)
bei System.Web.Script.Services.WebServiceMethodData.StrongTypeParameters(IDictionary`2 rawParams)
bei System.Web.Script.Services.WebServiceMethodData.CallMethodFromRawParams(Object target, IDictionary`2 parameters)
bei System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary`2 rawParams)
bei System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)
长话短说:如何将反斜杠作为参数传递给JSONObject而不将其转义?
好吧,您可能认为我只是自己构建JSON字符串,但我真的想发送和接收包含Date属性的更复杂的对象/数组,我不想自己处理整个JSON生成。
答案 0 :(得分:1)
我遇到了同样的问题。在提交值之前,我执行replaceAll。对于Java和RegEx,它有很多可以正确转义的斜杠。
JSONObject json = new JSONObject();
json.put("input", "\\/Date(1279176056000)\\/");
String stringToSubmit = json.toString().replaceAll("\\\\\\\\", "\\\\");
答案 1 :(得分:0)
这是我自己的解决方案:
import java.util.Date;
public class DateConverter {
private static long TicksToMillisOffset = 621355968000000000L;
private static long TicksPerMillisecond = 10000L;
public static Long toTicks(Date date)
{
if (date == null) return null;
int offset = date.getTimezoneOffset() * 60;
long ms = date.getTime();
return (ms + offset) * TicksPerMillisecond + TicksToMillisOffset;
}
public static Date fromTicks(Long ticks)
{
return ticks == null
? null
: new Date((ticks - TicksToMillisOffset) / TicksPerMillisecond);
}
public static String toJSONString(Date date) {
return date != null ? date.toGMTString() : null;
}
public static Date fromJSONString(String string) {
// expected: "/Date(secondssinceepoch)/"
if (string.matches("^/Date\\(\\d+\\)/$")) {
String value = string.replaceAll("^/Date\\((\\d+)\\)/$", "$1");
return new Date(Long.valueOf(value));
}
else {
return new Date(Date.parse(string));
}
}
}
用法:
// deserialisation:
JSONObject json = GetJSONObjectFromNetWebService();
Poco item = new Poco();
item.id = json.getInt("Id");
item.name = json.GetString("Name");
item.dateValue = DateConverter.fromJSONString(json.getString("DateValue"));
// serialisation
JSONObject json = new JSONObject();
Poco item = GetPocoFromSomeWhereElse();
json.put("Id", item.id);
json.put("Name", item.name);
json.put("DateValue", DateConverter.toJSONString(item.dateValue));