Sunucu uygulaması eşleme URL modelinde / ve / * arasındaki fark


175

Tanıdık kod:

<servlet-mapping>
    <servlet-name>main</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>main</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Benim anlayışım /*şununla eşleşiyor http://host:port/context/*.

Nasıl /? Sadece http://host:port/contextkök ile eşleşmediğinden emin . Aslında kabul edecek http://host:port/context/hello, fakat reddedecek http://host:port/context/hello.jsp.

Herkes nasıl http://host:port/context/helloharitalandığını açıklayabilir mi?

Yanıtlar:


268

<url-pattern>/*</url-pattern>

/*Bir sunucu uygulaması böyle varsayılan servlet ve JSP servlet olarak servletcontainer tarafından sağlanan tüm servlet dahil olmak üzere tüm diğer servlet, geçersiz kılar. Ne istersen ateş et, o sunucuda sonuçlanacak. Bu nedenle sunucu uygulamaları için kötü bir URL kalıbıdır. Genellikle, sadece /*bir üzerinde kullanmak istersiniz Filter. Daha özel bir URL modelini dinleyen sunucuların herhangi birine çağrı yaparak isteğin devam etmesine izin verebilir FilterChain#doFilter().

<url-pattern>/</url-pattern>

/Başka sunucu uygulamasını geçersiz kılmaz. Yalnızca kayıtlı başka bir sunucu uygulamasına uymayan tüm istekler için sunucu uygulamasının yerleşik varsayılan sunucu uygulamasının yerini alır. Bu normalde yalnızca statik kaynaklarda (CSS / JS / image / etc) ve dizin listelerinde çağrılır. Servletcontainer'ın yerleşik varsayılan sunucu uygulaması ayrıca HTTP önbellek istekleri, medya (ses / video) akışı ve dosya indirme özgeçmişleriyle de başa çıkabilir. Genellikle, aksi tam önemsiz değil tüm görevleri bakmak zorunda kalacak şekilde (JSF araç kütüphanesi varsayılan sunucu uygulamasını geçersiz istemiyorum OmniFaces bir sahip açık kaynak örneği). Bu da sunucu uygulamaları için kötü bir URL kalıbıdır. JSP sayfalarının neden bu sunucu uygulamasına çarpmadığına gelince, servletcontainer'ın yerleşik JSP sunucu uygulamasının çağrılması gerekir; bu zaten varsayılan olarak daha spesifik URL modelinde eşlenir *.jsp.

<url-pattern></url-pattern>

Sonra da boş dize URL modeli var . Bağlam kökü istendiğinde bu çağrılacaktır. Bu, <welcome-file>herhangi bir alt klasör istendiğinde çağrılmayan yaklaşımdan farklıdır . Bu, büyük olasılıkla bir " ana sayfa sunucu uygulaması " istemeniz durumunda aradığınız URL modelidir . Ben sadece boş dize URL kalıbı ve eğik çizgi URL kalıbı /tam olarak başka bir şekilde tanımlanması sezgisel olarak beklediğiniz itiraf etmeliyim , bu yüzden çok sayıda yeni başlayanlar bu konuda karışık var anlayabiliyorum. Ama olan budur.

Ön Denetleyici

Eğer gerçekte bir ön denetleyicisi servlet'dir sahip niyetinde, o zaman iyi gibi daha spesifik bir URL modeline üzerinde eşlemek olur *.html, *.do, /pages/*, /app/*, vb ortak bir URL modeline ön kontrolör URL kalıbı ve kapak statik kaynakları uzak gizleyebilirsiniz gibi /resources/*, /static/*vb bir servlet filtre yardımıyla. Ayrıca bkz . / * İle eşlenen ön denetleyici sunucu uygulaması tarafından statik kaynakların nasıl önleneceği . Spring MVC'nin yerleşik bir statik kaynak sunucu uygulamasına sahip olması gerektiği için, bu nedenle /Spring'de statik kaynaklar için ortak bir URL kalıbı yapılandırırsanız ön denetleyicisini eşleyebilirsiniz . Ayrıca bkz . Spring MVC'de statik içerik nasıl kullanılır?


9
Teşekkürler. Biraz araştırma yaptıktan sonra, ince bir noktayı açıklığa kavuşturmak istiyorum. / web sunucusunun yüklediği varsayılan sunucu uygulamasının üzerine yazar. Örneğin, Tomcat statik kaynaklar sunan bir DefaultServlet kurar. Varsayılan sunucu uygulamasının (büyük olasılıkla istenmeyen) bir yan etki olarak kullanılması / kaldırılması.
Candy Chiu

Buna "üzerine yazma" demezdim, "değiştiririm" derdim. Varsayılan sunucu uygulamasını böyle değiştirmek yararlı olabilir.
BalusC

1
<url-pattern> </url-pattern> bir hata
ince

Hata mesajı, IDE'm değil tomcat'ten geliyordu; Ancak, Tomcat 6 kullanıyorum, bu yüzden muhtemelen sorun;)
ince

2
@ BalusC, lütfen bana hangi /**desenin işaret ettiğini söyler misiniz ?
Sajib Acharya

45

BalusC'nin cevabını haritalama kuralları ve bir örnekle desteklemek istiyorum.

Servlet 2.5 spesifikasyonundan eşleme kuralları:

  1. Tam URL'yi eşle
  2. Joker karakter yollarını eşleme
  3. Harita uzantıları
  4. Varsayılan sunucu uygulamasına eşleme

Örneğimizde üç sunucu uygulaması var. / bizim tarafımızdan yüklenen varsayılan sunucu uygulamasıdır. Tomcat, jsp ve jspx için iki sunucu uygulaması kurar. Yani haritayahttp://host:port/context/hello

  1. Sonraki tam URL sunucu uygulaması yüklenmedi.
  2. Sırada yüklü joker karakter yolu sunucu uygulamaları yok.
  3. Sırada hiçbir uzantıyla eşleşmiyor.
  4. Varsayılan sunucu uygulamasına eşleyin, geri dönün.

Haritaya http://host:port/context/hello.jsp

  1. Sonraki tam URL sunucu uygulaması yüklenmedi.
  2. Sırada yüklü joker karakter yolu sunucu uygulamaları yok.
  3. Uzatma sunucu uygulaması bulundu, geri dön.

25

Belki de 404saatlerce acı çektiğim için URL'lerin nasıl haritalandığını bilmeniz gerekir . İki tür işleyici işleme isteği vardır. BeanNameUrlHandlerMappingve SimpleUrlHandlerMapping. Bir tanımladığımızda servlet-mapping, kullanıyoruz SimpleUrlHandlerMapping. Bilmemiz gereken bir şey, bu iki işleyicinin alwaysUseFullPathvarsayılan olarak adlandırılan ortak bir özelliği paylaşmasıdır false.

falseburada Spring, bir url'yi bir denetleyiciye eşlemek için tam yolu kullanmayacağı anlamına gelir. Bu ne demek? Bir aşağıdakileri tanımladığınızda servlet-mapping:

<servlet-mapping>
    <servlet-name>viewServlet</servlet-name>
    <url-pattern>/perfix/*</url-pattern>
</servlet-mapping>

işleyici aslında *denetleyiciyi bulmak için parçayı kullanır. Örneğin, aşağıdaki denetleyici 404şunu kullanarak talep ettiğinizde bir hatayla karşılaşır:/perfix/api/feature/doSomething

@Controller()
@RequestMapping("/perfix/api/feature")
public class MyController {
    @RequestMapping(value = "/doSomething", method = RequestMethod.GET) 
    @ResponseBody
    public String doSomething(HttpServletRequest request) {
        ....
    }
}

Mükemmel bir uyum, değil mi? Ama neden 404. Daha önce de belirtildiği gibi, varsayılan değeri alwaysUseFullPathfalse şeklindedir, yani isteğinizde yalnızca /api/feature/doSomethingkarşılık gelen bir Denetleyici bulmak için kullanılır, ancak bu yolla ilgilenen hiçbir Denetleyici yoktur. URL'nizi değiştirmeniz /perfix/perfix/api/feature/doSomethingveya perfixMyController tabanından kaldırmanız gerekir @RequestingMapping.


8

Bence Candy'nin cevabı çoğunlukla doğru. Başka türlü düşündüğüm küçük bir kısım var.

Ana makineyi eşlemek için: bağlantı noktası / context / hello.jsp

  1. Sonraki tam URL sunucu uygulaması yüklenmedi.
  2. Bulunan joker karakter yolları sunucuları , dönüş.

Neden "/ *" host: port / context / hello ile eşleşmediğine inanıyorum, çünkü "/ hello" yerine bir dosya yerine bir yol olarak davranıyor (çünkü bir uzantısı yok).


2

Arasındaki temel fark, /*ve /haritalama ile bir sunucu uygulaması olduğunu /*bir uzantısı eşleme (gibi herhangi bir sunucu uygulaması öncesinde seçilecektir *.htmlharitalama ile bir sunucu uygulaması ise,) /uzantısı eşlemeler olarak kabul edilir (ve bu olduğu mühim bir istek için kullanılacak sonra seçilecektir t Başka bir şeyle eşleşir --- "varsayılan sunucu uygulamasıdır").

Özellikle, bir /*haritalama her zaman bir /haritalamadan önce seçilecektir . İkisinden birinin olması, isteklerin kapsayıcının kendi varsayılan sunucu uygulamasına ulaşmasını önler.

Her ikisi de yalnızca tam eşleşmeler (gibi /foo/bar) olan ve yol eşlemelerinden /*(gibi /foo/*) daha uzun olan sunucu uygulamaları eşleştirmelerinden sonra seçilecektir . Boş dize eşlemenin bağlam kökü ( http://host:port/context/) ile tam olarak eşleştiğini unutmayın .

Http://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html adresindeki sürüm 3.1'de bulunan Java Servlet Belirtimi'nin Bölüm 12'sine bakın .

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.