Bahar ile isteğe bağlı bir yol değişkeni yapabilir miyim?


187

Spring 3.0 ile isteğe bağlı bir yol değişkenim olabilir mi?

Örneğin

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

Burada istiyorum /json/abcveya /jsonaynı yöntemi çağırmak için.
Açık bir geçici çözüm typeistek parametresi olarak bildirilir:

@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();
}

ve sonra /json?type=abc&track=aaya /json?track=rrda çalışacak

Yanıtlar:


194

İsteğe bağlı yol değişkenleriniz olamaz, ancak aynı hizmet kodunu çağıran iki denetleyici yönteminiz olabilir:

@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: Bu zorlayıcı bir nedendir değil bence yol değişkenlerini kullanmak. Kombinatoryal proliferasyon hızlı bir şekilde kontrolden çıkabilir.
skaffman

9
Aslında, isteğe bağlı bileşenlerle doldurulurken yol bu kadar karmaşık olamayacağı için değil. Birden fazla veya en fazla iki isteğe bağlı yol öğeniz varsa, bunlardan birkaçını parametre istemek için değiştirmeyi ciddi olarak düşünmelisiniz.
Patrick Cornelissen

1
Ve bazı insanlar için, ikinci kontrolör yönteminin birinci kontrolör yöntemini çağırması da işe yarayabilir, örneğin farklı parametre başka bir yolla sağlanabilirse
chrismarx

3
Lütfen yanıtınızı güncellemeyi düşünün, Spring'in yeni sürümünde iki denetleyici yöntemi oluşturmak yerine aşağıdaki @RequestMappinggibi iki değerle kullanabiliriz : stackoverflow.com/questions/17821731/…
csharpfolk

omg bu uç noktaları nasıl koruyorsunuz? Ve eğer tek bir yol değişkeni yerine 5 varsa, benim için matematik, kaç bitiş noktası yapardınız? Bana bir iyilik yap ve değiştir Lütfen @PathVariableetmek@RequestParam
Guilherme Alencar

114

Eğer bahar 4.1 ve Java 8 kullanıyorsanız kullanabileceğiniz java.util.Optionalyerleşik olduğu @RequestParam, @PathVariable, @RequestHeaderve @MatrixVariableBahar 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"
    }       
}

bunun işe yarayacağından emin misin? Buradaki kendi cevabınız , yolda {type} yoksa denetleyicinin vurulmayacağını gösterir. PathVariable Map'in daha iyi bir yaklaşım veya ayrı kontrolörler kullanmak olduğunu düşünüyorum.
Anshul Tiwari

4
Evet sadece varsa "/json/{type}"ve türü yoksa vurmak olmaz (bağlantılı cevabım önerdiği gibi) ama burada var value = {"/json/{type}", "/json" }. Yani herhangi biri eşleşen denetleyici yöntemi vurulur.
Aniket Thakur

Aynı değer vb. Türlerin RequestParam ve RequestParam olması da mümkün müdür?
zygimantus

Çalışıyor, ancak yine de denetleyicinin işlevi çağrılmayacak çünkü orada bir parametre bekliyor
EliuX

15
Bu çalışır ve Bahar 4.3.3'ten beri @PathVariable(required = false), değişken mevcut değilse de devam edebilir ve null alabilirsiniz.
Nicolai Ehemann

76

@PathVariable ek açıklamasını kullanarak yol değişkenlerinin Haritasını da enjekte edebileceğiniz iyi bilinmemektedir. Bu özelliğin Bahar 3.0'da kullanılabilir olup olmadığından veya daha sonra eklenmiş olup olmadığından emin değilim, ancak örneği çözmenin başka bir yolu:

@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
Her zaman kullanıyorum. Farklı uri türlerini işlemek için tek bir yöntem istediğimde kullanışlı geliyor: {"/ json / {type}", "/ json / {type} / {xyz}", "/ json / {type} / {abc} "," / json / {type} / {abc} / {bir şey} "," / json "}
Vaibs

25

Şunları kullanabilirsiniz:

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

bir yol yerine isteğe bağlı parametreler için


1
Bu sürüme özel, öyle görünüyor. Bahar 3'e gitme
Stu Thompson

5
Şu anda bir bahar 3.1 projesi için bu yöntemi kullanıyor ve dokümanlar 2.5+ için çalıştığını söylüyor, bu yüzden kesinlikle Bahar 3 için çalışıyor. EDIT: source .
Evan B.

22
Doğru, ama sorunun konusu bu değil. İstek parametrelerini kullanmak gerçekten soruda "Tek bir geçici çözüm" olarak belirtilir , ancak sorunun kendisi yol parametreleriyle ilgilidir. Bu, isteğe bağlı yol parametreleri için bir çözüm değildir.
Arjan

9
PathVariable ve RequestParam farklıdır.
Zamansız

10

Spring 5 / Spring Boot 2 örnekleri:

engelleme

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

tepkili

@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'ın yorumu ve wildloop'un cevabının basitleştirilmiş örneği (Bahar 4.3.3+ ile çalışır), temel olarak required = falseşimdi kullanabilirsiniz :

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



-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
Cevabınızdaki bazı metinlerde bunu düzenlemek isteyebilirsiniz, bunun neden eldeki sorunu çözmeye katkıda bulunduğunu düşündüğünüzü açıklayabilirsiniz (4 yıl sonra).
Qirel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.