ด้วย Spring ฉันสามารถสร้างตัวแปรพา ธ เสริมหรือไม่?


187

ด้วย Spring 3.0 ฉันสามารถมีตัวแปรพา ธ เสริมได้ไหม?

ตัวอย่างเช่น

@RequestMapping(value = "/json/{type}", method = RequestMethod.GET)
public @ResponseBody TestBean testAjax(
        HttpServletRequest req,
        @PathVariable String type,
        @RequestParam("track") String track) {
    return new TestBean();
}

ที่นี่ฉันต้องการ/json/abcหรือ/jsonจะเรียกวิธีการเดียวกัน
วิธีแก้ปัญหาที่ชัดเจนหนึ่งประกาศtypeเป็นพารามิเตอร์คำขอ:

@RequestMapping(value = "/json", method = RequestMethod.GET)
public @ResponseBody TestBean testAjax(
        HttpServletRequest req,
        @RequestParam(value = "type", required = false) String type,
        @RequestParam("track") String track) {
    return new TestBean();
}

จากนั้น/json?type=abc&track=aaหรือ/json?track=rrจะทำงาน

คำตอบ:


194

คุณไม่สามารถเลือกตัวแปรพา ธ ได้ แต่คุณสามารถมีวิธีควบคุมได้สองวิธีซึ่งเรียกรหัสบริการเดียวกัน:

@RequestMapping(value = "/json/{type}", method = RequestMethod.GET)
public @ResponseBody TestBean typedTestBean(
        HttpServletRequest req,
        @PathVariable String type,
        @RequestParam("track") String track) {
    return getTestBean(type);
}

@RequestMapping(value = "/json", method = RequestMethod.GET)
public @ResponseBody TestBean testBean(
        HttpServletRequest req,
        @RequestParam("track") String track) {
    return getTestBean();
}

5
@Shamik: นี่เป็นเหตุผลที่น่าสนใจที่จะไม่ใช้ตัวแปรพา ธ ในความคิดของฉัน การแพร่กระจายของ combinatorial สามารถหลุดออกจากมือได้อย่างรวดเร็ว
skaffman

9
อันที่จริงไม่ได้เพราะเส้นทางไม่สามารถซับซ้อนได้ในขณะที่เต็มไปด้วยองค์ประกอบเสริม หากคุณมีองค์ประกอบพา ธ ทางเลือกมากกว่าหนึ่งรายการหรือมากกว่าสองรายการคุณควรพิจารณาเปลี่ยนองค์ประกอบบางอย่างเพื่อขอพารามิเตอร์อย่างจริงจัง
Patrick Cornelissen

1
และสำหรับบางคนการใช้วิธีควบคุมตัวที่สองเรียกวิธีตัวควบคุมแรกอาจใช้งานได้เช่นกันถ้าพารามิเตอร์อื่นสามารถให้ได้ด้วยวิธีอื่น
chrismarx

3
โปรดพิจารณาอัปเดตคำตอบของคุณแทนที่จะสร้างวิธีควบคุมสองวิธีใน Spring เวอร์ชั่นใหม่กว่านี้เราอาจใช้@RequestMappingกับสองค่าดังนี้: stackoverflow.com/questions/17821731/…
csharpfolk

คุณคาดหวังว่าจะรักษาจุดปลายเหล่านี้ได้อย่างไร และถ้าแทนที่จะมีเพียงหนึ่งตัวแปรพา ธ ที่เรามี 5 ทำคณิตศาสตร์ให้ฉันคุณจะทำจุดสิ้นสุดกี่จุด โปรดฉันหน่อยได้ไหมและแทนที่@PathVariableไป@RequestParam
Guilherme โลคอน

113

หากคุณกำลังใช้ Spring 4.1 และ Java 8 คุณสามารถใช้java.util.Optionalซึ่งได้รับการสนับสนุนใน@RequestParam, @PathVariable, @RequestHeaderและ@MatrixVariableในฤดูใบไม้ผลิ MVC -

@RequestMapping(value = {"/json/{type}", "/json" }, method = RequestMethod.GET)
public @ResponseBody TestBean typedTestBean(
    @PathVariable Optional<String> type,
    @RequestParam("track") String track) {      
    if (type.isPresent()) {
        //type.get() will return type value
        //corresponds to path "/json/{type}"
    } else {
        //corresponds to path "/json"
    }       
}

คุณแน่ใจว่าจะใช้งานได้ไหม คำตอบของคุณเองที่นี่แสดงให้เห็นว่าตัวควบคุมจะไม่ถูกตีหาก {type} หายไปจากเส้นทาง ฉันคิดว่าแผนที่ PathVariable จะเป็นวิธีที่ดีกว่าหรือใช้ตัวควบคุมแยกกัน
Anshul Tiwari

4
ใช่ถ้าคุณเพียงแค่ต้อง"/json/{type}"และชนิดไม่อยู่มันจะไม่ตี (เป็นคำตอบของฉันเชื่อมโยงให้เห็น) value = {"/json/{type}", "/json" }แต่ที่นี่คุณมี ดังนั้นหากผู้ใดที่ตรงกับวิธีการควบคุมจะถูกตี
Aniket Thakur

เป็นไปได้ว่าค่าเดียวกัน ฯลฯ ประเภทจะเป็น RequestParam และ RequestParam ด้วยหรือไม่
zygimantus

ใช้งานได้ แต่อย่างไรก็ตามฟังก์ชันของตัวควบคุมจะไม่ถูกเรียกใช้เพราะคาดว่าจะมีพารามิเตอร์อยู่ที่นั่น
EliuX

15
วิธีนี้ใช้งานได้และตั้งแต่ Spring 4.3.3 คุณสามารถไปด้วย@PathVariable(required = false)และรับค่าว่างถ้าตัวแปรนั้นไม่มีอยู่
Nicolai Ehemann

76

ไม่เป็นที่ทราบกันดีว่าคุณสามารถฉีด Map of the path path โดยใช้คำอธิบายประกอบ @PathVariable ฉันไม่แน่ใจว่าคุณลักษณะนี้มีให้ใน Spring 3.0 หรือเพิ่มในภายหลัง แต่นี่เป็นอีกวิธีในการแก้ไขตัวอย่าง:

@RequestMapping(value={ "/json/{type}", "/json" }, method=RequestMethod.GET)
public @ResponseBody TestBean typedTestBean(
    @PathVariable Map<String, String> pathVariables,
    @RequestParam("track") String track) {

    if (pathVariables.containsKey("type")) {
        return new TestBean(pathVariables.get("type"));
    } else {
        return new TestBean();
    }
}

1
ฉันใช้มันตลอดเวลาสิ่งนี้มีประโยชน์เมื่อฉันต้องการวิธีการเดียวในการจัดการ uri ประเภทต่างๆเช่น: {"/ json / {type}", "/ json / {type} / {xyz}", "/ json / {type} / {abc} "," / json / {type} / {abc} / {
some

25

คุณสามารถใช้:

@RequestParam(value="somvalue",required=false)

สำหรับ params เผื่อเลือกแทนที่จะเป็น pathVariable


1
นี่เป็นรุ่นเฉพาะดูเหมือนว่า ห้ามพลาดสำหรับ Spring 3
Stu Thompson

5
ปัจจุบันใช้วิธีนี้สำหรับฤดูใบไม้ผลิ 3.1 โครงการและเอกสารบอกว่ามันเหมาะกับ 2.5+ จึงทำงานแน่นอนสำหรับฤดูใบไม้ผลิ 3. แก้ไข: แหล่งที่มา
Evan B.

22
จริง แต่นี่ไม่ใช่คำถามที่เกี่ยวกับ การใช้พารามิเตอร์คำร้องขอนั้นถูกกล่าวถึงในคำถามเป็น"วิธีแก้ปัญหาหนึ่งที่ชัดเจน"แต่คำถามนั้นเกี่ยวกับพารามิเตอร์พา ธ นี่ไม่ใช่โซลูชันสำหรับพารามิเตอร์พา ธ เผื่อเลือก
Arjan

9
PathVariable และ RequestParam นั้นแตกต่างกัน
ตลอดกาล

10

ตัวอย่าง Spring 5 / Spring Boot 2:

การปิดกั้น

@GetMapping({"/dto-blocking/{type}", "/dto-blocking"})
public ResponseEntity<Dto> getDtoBlocking(
        @PathVariable(name = "type", required = false) String type) {
    if (StringUtils.isEmpty(type)) {
        type = "default";
    }
    return ResponseEntity.ok().body(dtoBlockingRepo.findByType(type));
}

ปฏิกิริยา

@GetMapping({"/dto-reactive/{type}", "/dto-reactive"})
public Mono<ResponseEntity<Dto>> getDtoReactive(
        @PathVariable(name = "type", required = false) String type) {
    if (StringUtils.isEmpty(type)) {
        type = "default";
    }
    return dtoReactiveRepo.findByType(type).map(dto -> ResponseEntity.ok().body(dto));
}

6

ตัวอย่างที่ง่ายกว่าของความคิดเห็นของ Nicolai Ehmann และคำตอบของ wildloop (ใช้ได้กับ Spring 4.3.3+) โดยทั่วไปคุณสามารถใช้งานได้ทันทีrequired = false:

  @RequestMapping(value = {"/json/{type}", "/json" }, method = RequestMethod.GET)
  public @ResponseBody TestBean testAjax(@PathVariable(required = false) String type) {
    if (type != null) {
      // ...
    }
    return new TestBean();
  }

3

ตรวจสอบSpring 3 WebMVC - ตัวแปรพา ธเพิ่มเติม มันแสดงให้เห็นบทความของการสร้างส่วนขยายไปยัง AntPathMatcher เพื่อเปิดใช้งานตัวแปรพา ธ เผื่อเลือกและอาจช่วยได้ เครดิตทั้งหมดให้แก่Sebastian Heroldสำหรับการโพสต์บทความ



-5
$.ajax({
            type : 'GET',
            url : '${pageContext.request.contextPath}/order/lastOrder',
            data : {partyId : partyId, orderId :orderId},
            success : function(data, textStatus, jqXHR) });

@RequestMapping(value = "/lastOrder", method=RequestMethod.GET)
public @ResponseBody OrderBean lastOrderDetail(@RequestParam(value="partyId") Long partyId,@RequestParam(value="orderId",required=false) Long orderId,Model m ) {}

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