Tôi có nên sử dụng loại Ngày trong JAX-RS @PathParam không?


9

Đây là những gì tôi nghĩ về việc thực hiện trên máy chủ JEE Glassfish bằng Jersey.

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

Tôi thích ý tưởng có thể nói với mọi người về việc sử dụng dịch vụ web RESTful này rằng "Ngày ở đây là bất cứ điều gì hoạt động với lớp Date trong Java". Điều đó khá đơn giản theo quan điểm rằng họ chỉ cần nhìn vào thông số Ngày và họ sẽ có một mô hình hoạt động mà họ có thể thử nghiệm.

Vấn đề mà tôi lo lắng là khi tôi làm điều này, JAX-RS không đẹp lắm khi Date () không giống như những gì nó có trong hàm tạo. Vì Date () đưa ra một lỗi nếu nó không thể phân tích những gì nó đưa ra (như nếu bạn chuyển chuỗi "hôm nay" thay vì ngày thực sự), máy chủ JEE trả về lỗi 404.

Đây có phải là một thực hành tốt? Có cách nào tốt hơn để làm điều này mà tôi không nghĩ đến?

Câu trả lời:


8

Nghe có vẻ là một ý tưởng tồi. Đối với một điều, hàm tạo Ngày mà bạn đang dựa vào đã bị từ chối vì Java 1.1 có lợi cho DateFormat.parseDate (), vì không rõ các chuỗi nên được phân tách thành các ngày như thế nào, vì các quy tắc khác nhau đối với các địa phương khác nhau.

Đề xuất của tôi sẽ là sử dụng một định dạng cụ thể, tốt nhất là yyyy-MM-dd được quốc tế hiểu và sử dụng DateFormat để phân tích ngày từ một chuỗi trong dịch vụ của bạn, giúp hiểu rõ cách sử dụng dịch vụ web và cho phép bạn để tuân theo bất cứ quy ước chuẩn nào để trả về các thông báo lỗi là cho các dịch vụ web của bạn khi có sự cố.


11

Tôi đang sử dụng một lớp tùy chỉnh DateParam:

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

Lớp được định nghĩa là:

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

Nếu tham số trống thì bạn sẽ nhận được ngày null. Bạn có thể mở rộng DateParambằng trường tĩnh cuối cùng cho các giá trị ngày không xác định. Điều này sẽ làm cho việc kiểm tra các thông số ngày không xác định rõ ràng hơn.

Một nhược điểm ở đây là với mỗi DateParam, một phiên bản mới của SimpleDateFormat được tạo. Tuy nhiên, vì SimpleDateFormat không an toàn cho luồng, chúng tôi không thể sử dụng lại dễ dàng.


3
1+. Java 8 đã giới thiệu một luồng an toàn DateTimeFormatter. Đối với Java <= 7, tôi sẽ sử dụng mộtThreadLocal
Anthony Accioly

3

Ai sẽ sử dụng dịch vụ của bạn? Họ sẽ bận tâm tìm kiếm đặc tả của Datelớp và tìm ra loại chuỗi nào nó sẽ phân tích? Tôi sẽ không, ngay cả khi là một lập trình viên Java, tôi sẽ biết nơi để tìm ;-)

Tôi nghĩ trước tiên bạn nên nói với người dùng của mình về URI của bạn sẽ như thế nào, vd

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

và sau đó tìm cách để Jersey giúp bạn phân tích bất kỳ định dạng ngày nào bạn chọn. Điều đó có thể có nghĩa là sử dụng một Dateloại tham số và có thể chỉ định biểu thức chính quy trong @Pathchú thích của bạn , như

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

hoặc sử dụng một số lớp khác có khả năng phân tích một ngày theo định dạng của bạn. Cách xử lý các URI không khớp với thông số bạn cung cấp cho người dùng của bạn là một điều khác bạn nên quyết định cách xử lý độc lập với bất kỳ điều nào ở trên (trả lại tài nguyên mặc định? Trả về lỗi 404?).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.