Я использую ServiceStack 4.5.6 с Visual Studio 2015. В моей текущей ситуации я использую SS как клиент. Сервер REST написан на Java сторонней компанией. Я написал классы моделей, DTO и т. д., Чтобы они соответствовали маршрутам сервера.
Но теперь у меня следующие проблемы: Обмен целыми числами или строками не проблема. Но, похоже, действительно сложно обмениваться значениями DateTime.
Кажется, что Java использует строки формата DateTime, отличные от C# / ServiceStack, и сейчас я не могу найти общую.
Вот несколько примеров, которые я получил от разработчика сервера:
Ява:
2012-06-30T12:30:40+01:00
2012-06-30T12:30:40Z
2012-06-30T12:30:40Z[GMT]
2012-06-30T12:30:40Z[UT]
2012-06-30T12:30:40Z[UTC]
2016-11-05 13:45
2016-05-15 20:15:23.340
Поэтому в большинстве случаев Java добавляет Z или [часовой пояс]. Мне не удалось создать какой-либо из этих форматов с помощью ServiceStack.
Например. со следующим кодом:
using (var scope = JsConfig.BeginScope())
{
scope.DateHandler = DateHandler.ISO8601;
return client.Post(request);
}
Я получаю такой результат
2018-04-09T17:14:19.1201876+02:00
что почти похоже на первый пример java, но наносекунд - это слишком много.
Я знаю, что могу использовать собственный формат, как описано здесь: ServiceStack - есть ли способ заставить все сериализованные даты использовать определенный DateTimeKind? Возможно ли использовать такой настраиваемый формат только для определенного JsonServiceClient? Я не могу использовать его глобально для всего моего приложения.
С уважением, Даниэль




Невозможно заставить разные ответы для определенных клиентов ServiceClient.
Если вам нужно изменить реализацию DateTime в Java, вы можете заменить существующий DateTime impl своим собственным настройка сериализатора даты, используемого сериализатором Gson, например:
JsonServiceClient client = new JsonServiceClient(baseUrl);
GsonBuilder gsonBuilder = client.getGsonBuilder();
gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return json == null ? null : Utils.parseDate(json.getAsString());
}
});
client.setGson(gsonBuilder.disableHtmlEscaping().create());
В противном случае альтернативный способ обеспечить точную отформатированную дату - сериализовать ее как строку на C# и заставить ваши DTO возвращать строку.
Я не могу сказать вам точных деталей, но должен сказать, что вам лучше всего подходит формат ISO 8601, международный стандарт. Ваши примерные строки соответствуют этому стандарту или близки к нему, поэтому я надеюсь, что это будет жизнеспособным.
Java: ваши первые два примера, 2012-06-30T12:30:40+01:00 и 2012-06-30T12:30:40Z, - это ISO 8601. Z - это распространенный способ обозначения смещения 0, это нигде не должно вызывать никаких проблем. Квадратные скобки с часовыми поясами в следующих примерах относятся к Java, кроме того, что они также соответствуют ISO. Если вы получаете такие строки, вам придется убрать скобки или просто проанализировать строки, насколько это возможно, и игнорировать любые неанализируемые символы. Насколько мне известно, строки, в которых отсутствует T между датой и временем, не соответствуют.
ServiceStack: 2018-04-09T17:14:19.1201876+02:00 - это точно ISO 8601. У Java не должно возникнуть проблем с принятием этого формата. Количество десятичных знаков является свободным (и они не являются обязательными, могут присутствовать или нет).
OffsetDateTime odt = OffsetDateTime.parse( "2018-04-09T17:14:19.1201876+02:00" ) ;
Я не знаком с ServiceStack и, очевидно, не знаю этого конкретного сервера Java, так что это как можно ближе.
Кроме того, я предлагаю просто удалить все вхождения [GMT], [UT] и [UTC] после Z, а затем обработать, как показано в Ответе. Для последних двух примеров в Вопросе без зоны или смещения замените ПРОБЕЛ в середине на T и проанализируйте как LocalDateTime без какой-либо концепции часового пояса или offset-from-UTC: LocalDateTime.parse( "2016-11-05 13:45".replace( " " , "T" ) )
Вы правы, спасибо. Сейчас я буду использовать формат ISO8601, например 2018-04-09T17:14:19.1201876+02:00 Я думал, что Java не поймет этот формат, так как есть десятичная часть, которая не включена в примеры. Но после разговора с разработчиком нашего сервера это не кажется проблемой.
На стороне сервера не используется ServiceStack, поэтому это не поможет. Но сейчас я выберу DateHandler.ISO8601. Думаю, я нашел свою ошибку: для тестирования я использовал REST-клиент Postman. Там я забыл закодировать знак +, поэтому получил странные результаты.