代码之家  ›  专栏  ›  技术社区  ›  Jürgen Steinblock

.javajObjor对象.NET WebService反序列化到DATITEME()

  •  2
  • Jürgen Steinblock  · 技术社区  · 14 年前

    我有一个.NET WebService,它应该通过JSON与Java应用程序通信。

    现在我在服务器端有一个方法,如下所示:

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public DateTime GetDate(DateTime input)
        {
            return input;
        }
    

    从C应用程序,我可以发送一个接收日期时间值。按照惯例,日期值序列化为:

    \/Date(1279176056000)\/
    

    其中,数字定义为自epoch以来的秒数。 因此,如果我想调用该服务,我的JSON请求字符串必须如下所示:

    {"input":"\/Date(1279176056000)\/"}
    

    Howevery,我不知道如何用JSON.Org.*类在Java方面实现这一点。
    问题是:如果我使用此代码:

    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字符串,但我真的想发送和接收包含日期属性的更复杂的对象/数组,我不想自己处理整个JSON生成。

    2 回复  |  直到 13 年前
        1
  •  1
  •   David Silva Smith    13 年前

    我也有同样的问题。在提交值之前,我执行replaceall。对于Java和ReGEX来说,它有大量的斜杠要正确地逃脱。

    JSONObject json = new JSONObject();
    json.put("input", "\\/Date(1279176056000)\\/");
    
    String stringToSubmit = json.toString().replaceAll("\\\\\\\\", "\\\\");
    
        2
  •  0
  •   Jürgen Steinblock    13 年前

    以下是我自己的解决方案:

    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));