2012-11-15 10 views
10
<servlet-mapping> 
    <servlet-name>testServlet</servlet-name> 
    <url-pattern>/test/*</url-pattern> 
</servlet-mapping> 

Se si preme /test/pagina, quanto sopra funzionerà. Tuttavia, premendo /test o /test/ non funzionerà. Sto utilizzando Spring MVC, e la mia mappatura richiesta è la seguente:In una mappatura servlet in Spring MVC come si esegue il mapping della radice di una directory di pattern URL?

@RequestMapping(value = {"","/"}) 

EDIT:

Sono nel processo di verifica con un progetto indipendente, ma questo sembra essere un bug con Spring's UrlPathHelper. Il seguente metodo restituisce un percorso errato quando c'è un contesto e un percorso servlet e si colpisce il servlet senza una barra finale.

public String getPathWithinApplication(HttpServletRequest request) { 
    String contextPath = getContextPath(request); 
    String requestUri = getRequestUri(request); 
    if (StringUtils.startsWithIgnoreCase(requestUri, contextPath)) { 
     // Normal case: URI contains context path. 
     String path = requestUri.substring(contextPath.length()); 
     return (StringUtils.hasText(path) ? path : "/"); 
    } 
    else { 
     // Special case: rather unusual. 
     return requestUri; 
    } 
} 

A titolo di esempio diciamo che ho un contesto di "admin" e la seguente servlet-mapping:

<servlet-mapping> 
    <servlet-name>usersServlet</servlet-name> 
    <url-pattern>/users/*</url-pattern> 
</servlet-mapping> 

Ora ho una mappatura richiesta in uno dei miei controllori come questo:

@RequestMapping(value = {"","/"}) 

Se colpisco /admin/utenti non funzionerà. Tuttavia, se colpisco /admin/users/ funzionerà. Ora, se cambio la mappatura richiesta al seguente allora saranno sia il lavoro:

@RequestMapping(value = {"/users","/"}) 

Tuttavia, ora le URL /admin/utenti/utenti potranno anche lavorare (che non è quello che vorrei).

risposta

2

Prima di tutto, la differenza tra il mapping del servlet di dispatcher a "/" e a "/ *". C'è una differenza!

Quando si esegue il mapping su "/ *", tutte le richieste di URL (incluso qualcosa come "/WEB-INF/jsp/.../index.jsp") sono mappate al servlet del dispatcher.

In secondo luogo, quando si utilizza Spring + Tiles e si restituisce JSP nella definizione di tile, viene considerato come una richiesta di inoltro interna e gestito dallo stesso servlet della richiesta originale. Nel mio esempio, invoco l'URL root "/", che viene correttamente catturato dal metodo home(), e poi inoltrato a "index.jsp" da Tiles, che viene nuovamente gestito da Servlet Dispatcher. Ovviamente, il servlet del dispatcher non può gestire "index.jsp", perché non esiste alcun controller per questo.

Sì, è brutto, ma sembra che questo sia il modo in cui funziona.

Quindi, l'unica soluzione che ho trovato finora: per cambiare "/ *" torna a "/" in web.xml. In questo modo i JSP sono resi correttamente dal servlet jsp di Tomcat, credo, e non dal servlet di dispatcher. Sfortunatamente, questa correzione interromperà l'invio dell'URL ROOT da parte di Spring, quindi per ora devi lasciare l'idea di usare ROOT URL + Tiles.

Si prega di notare che l'aggiunta di mappatura servlet esplicito ".jsp -> Tomcat JSP in web.xml non aiuta, quando si utilizza "/ *", e fa schifo

ancora il problema non viene risolto. .

Anche questo è il problema in Spring MVC 3.0

+0

Il problema non è con l'utilizzo di un percorso di root. Se utilizzo un percorso root, vado sempre con '/' e '@RequestMapping (value = {" ","/"})'. Non ho mai avuto un problema con questo, e sto usando Tiles 2 e Spring MVC 3. Il problema è con la specificazione di un percorso servlet prima. Ogni volta che si specificano le informazioni sul percorso del servlet, il mapping delle richieste di Spring è tutto ciò che segue. Quindi tecnicamente, la stessa mappatura delle richieste dovrebbe funzionare perché è la radice del percorso del servlet. Tuttavia, questo non sembra essere il caso. –

3

mio setup di solito è questo:

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

controllore, dove suppongo che si desidera gestire /test e /test/ altrettanto:

@Controller 
public class MyController { 

    @RequestMapping("/test") 
    public String test() { 
     return "redirect:/welcome"; 
    } 

    @RequestMapping("/test/") 
    public String test() { 
     return "redirect:/welcome"; 
    } 

    @RequestMapping("/welcome") 
    public void test(ModelMap model) { 
     // do your stuff 
    } 
} 

impostazione come questa potrebbe causare DispatcherServlet per gestire le richieste per *.css e *.js file, che non è desiderato nella maggior parte dei casi. Penso che questo sia il problema descritto da Bhavik. Per tali risorse è possibile la ResourceController in questo modo:

<mvc:resources mapping="/css/**" location="/resources/css/" /> 
<mvc:resources mapping="/js/**" location="/resources/js/" /> 

file da /resources/css e /resources/js saranno serviti senza costringere a scrivere un controllo supplementare.

+0

Penso che questo non funzionerà come root controller –

+0

@BhavikAmbani perché no? – Yevgeniy

+0

La domanda riguarda il controller di root, per ulteriori informazioni leggi la mia risposta di seguito –

4

Yevgeniy è corretto, ma se il tuo DispatcherServlet è presa in consegna per il servlet predefinito, è necessario aggiungere questo al tuo web.xml:

<welcome-file-list> 
    <welcome-file>/</welcome-file> 
</welcome-file-list> 
+0

Non sono strano , È la strada giusta! –

0

Un modo senza tocco il file web.xml è di serie la mappa al percorso del file di benvenuto predefinito.

@RequestMapping("/index.html") 
0

Nel mio caso, ogni url stava lavorando ad eccezione della radice "/" URL.
Il problema era che non ho cancellato il file index.htm all'interno della cartella principale webapp dei miei progetti.

Problemi correlati