Чи слід використовувати тип дати в JAX-RS @PathParam?


9

Це те, про що я думаю робити на сервері JEE Glassfish за допомогою Джерсі.

@GET
@Path("/{name}/{date}")
public String getMessages(@PathParam("name") String name, @PathParam("date") Date date)

Мені подобається думка про те, щоб можна було сказати людям, які споживають цю RESTful веб-службу, що "Датою тут є все, що працює з класом Date на Java". З точки зору це досить просто, що вони можуть просто подивитися на специфікацію дати, і вони вже матимуть працюючу модель, яку вони можуть перевірити.

Проблема, яка мене хвилює, полягає в тому, що коли я роблю це, JAX-RS не дуже приємно, коли Date () не подобається те, що потрапляє в конструктор. Оскільки Date () видає помилку, якщо вона не може проаналізувати те, що їй дано (наприклад, якщо ви передасте їй рядок "сьогодні" замість реальної дати), сервер JEE повертає помилку 404.

Це хороша практика? Чи є кращий спосіб зробити це, про що я не думаю?

Відповіді:


8

Звучить погана ідея. З одного боку, конструктор Date, на який ви будете покладатися, був устарений з часу Java 1.1 на користь DateFormat.parseDate (), саме тому, що незрозуміло, яким чином слід розбирати рядки в датах, оскільки правила різні для різних місцевостей.

Моєю рекомендацією було б дотримуватися певного формату, бажано, міжнародно-розробленого yyyy-MM-dd, і використовувати DateFormat, щоб проаналізувати дату з рядка всередині вашої послуги, що дозволяє зрозуміти, як споживати веб-сервіс, і дозволяє вам дотримуватися будь-якої стандартної угоди щодо повернення повідомлень про помилки для ваших веб-служб, коли щось піде не так.


11

Я використовую спеціальний клас DateParam:

@GET
@Path("/{name}/{date}")
public String getMessages(@PathParam("name") String name, @PathParam("date") DateParam date)
  Date date = date.getDate();

Клас визначається як:

public class DateParam {
  private final Date date;

  public DateParam(String dateStr) throws WebApplicationException {
    if (isEmpty(dateStr)) {
      this.date = null;
      return;
    }
    final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    try {
      this.date = dateFormat.parse(dateStr);
    } catch (ParseException e) {
      throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
        .entity("Couldn't parse date string: " + e.getMessage())
        .build());
    }
  }

  public Date getDate() {
    return date;
  }
}

Якщо параметр порожній, ви отримаєте нульову дату. Ви можете розширити DateParamзагальнодоступне статичне остаточне поле для невизначених значень дати. Це зробить тестування на невизначені параметри дати більш зрозумілими.

Один недолік тут полягає в тому, що для кожного DateParam створюється новий примірник SimpleDateFormat. Однак, оскільки SimpleDateFormat не є безпечним для потоків, ми не можемо легко використовувати його повторно.


3
1+. Java 8 представила безпечний потік DateTimeFormatter. Для Java <= 7 я б використав:ThreadLocal
Ентоні Акціолій

3

Хто скористається вашою послугою? Чи будуть вони намагатися шукати специфікацію Dateкласу і з'ясувати, які рядки він буде розбирати? Я б не став, навіть якби програміст на Java, я знав би, де шукати ;-)

Я думаю, спочатку слід повідомити своїм користувачам, як будуть виглядати ваші URI, наприклад

.../your-resource-name/yyyy-MM-dd

а потім шукайте спосіб, як Джерсі допоможе вам розбирати будь-який формат дати, який ви вибрали. Це може означати використання Dateтипу параметра і, можливо, вказати регулярний вираз у вашій @Pathпримітці, наприклад

@Path(/{name}/{date: [0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]/)

або з використанням іншого класу, здатного аналізувати дату у вашому форматі. Як поводитися з URI, які не відповідають специфікаціям, які ви надаєте своїм користувачам, - це ще одна річ, вам слід вирішити, як поводитися незалежно від будь-якого з перерахованих вище (повернути ресурс за замовчуванням? Повернути помилку 404?).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.