ฉันควรใช้ประเภทวันที่ใน JAX-RS @PathParam หรือไม่


9

นี่คือสิ่งที่ฉันคิดเกี่ยวกับการทำบนเซิร์ฟเวอร์ JEE Glassfish โดยใช้ Jersey

@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
Anthony Accioly

3

ใครจะใช้บริการของคุณ พวกเขาจะรำคาญที่จะค้นหาข้อมูลจำเพาะของDateชั้นเรียนและคิดว่ามันจะแยกสตริงชนิดใด? ฉันจะไม่แม้ว่าจะเป็นโปรแกรมเมอร์ Java ฉันจะรู้ว่าจะดู ;-)

ฉันคิดว่าคุณควรบอกผู้ใช้ของคุณก่อนว่าลักษณะของ URI ของคุณจะเป็นเช่นไร

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

แล้วหาวิธีที่จะให้ Jersey ช่วยคุณในการแยกวิเคราะห์รูปแบบวันที่ที่คุณเลือก นั่นอาจหมายถึงการใช้Dateประเภทพารามิเตอร์และอาจระบุนิพจน์ปกติใน@Pathหมายเหตุประกอบของคุณเช่น

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

หรือใช้คลาสอื่นที่สามารถแยกวิเคราะห์วันที่ในรูปแบบของคุณ วิธีจัดการกับ URIs ที่ไม่ตรงกับข้อมูลจำเพาะที่คุณให้กับผู้ใช้ของคุณนั้นเป็นอีกสิ่งหนึ่งที่คุณควรตัดสินใจว่าจะจัดการกับสิ่งใด ๆ ข้างต้นได้อย่างอิสระ (คืนทรัพยากรเริ่มต้นหรือไม่กลับข้อผิดพลาด 404)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.