2014-09-18 8 views
7

Quando i miei file jsp sono all'interno della cartella WEB-INF (come /WEB-INF/file.jsp), posso accedervi da localhost: 8080/ProjectCtxtRoot /, ma non posso accedervi, se sono inseriti in/WEB-INF/jsp/file.jsp?Perché i file jsp all'interno della cartella WEB-INF funzionano, ma non collocati in una cartella sotto WEB-INF?

Ho cambiato il percorso nel tag welcome-list in web.xml come segue

<welcome-file-list> 
     <welcome-file>/JSP/fileName.jsp</welcome-file> 
</welcome-file-list> 

Ho cambiato anche il dispatcher-servlet.xml come segue

<bean id="jspViewResolver" 
      class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
      p:prefix="/WEB-INF/jsp/" 
      p:suffix=".jsp" /> 

Ancora non funziona . URL utilizzato per il caso di cui sopra sono

localhost:8080/ContextRoot/jsp/ 
localhost:8080/ContextRoot/jsp/fileName.jsp 
localhost:8080/ContextRoot/jsp/fileName 

e non funziona per qualsiasi URL sopra.

Ma funzionava quando

<welcome-file-list> 
     <welcome-file>/fileName.jsp</welcome-file> 
</welcome-file-list> 

dispatcher-servlet.xml come segue

<bean id="jspViewResolver" 
     class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
     p:prefix="/WEB-INF/" 
     p:suffix=".jsp" /> 

URL utilizzato per caso sopra è localhost: 8080/ContextRoot/e funziona.

Uso il server tomcat v 7.0. Rinnovo il mio progetto in Eclipse IDE, poi lo pulisco, lo costruisco, costruisco guerra usando l'installazione di mvn clean, quindi scelgo la guerra dalla home page di Tomcat Manager e la distribuisco. Lo faccio ogni volta.

Ecco come diapatcher-servlet.xml analizza tutto il processo. Mi limito a cambiare sezione particolare come sopra detto

<?xml version="1.0" encoding="UTF-8"?> 


<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:p="http://www.springframework.org/schema/p" 
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> 

    <mvc:annotation-driven/> 

    <context:component-scan base-package="com.projectName.www" /> 

    <!-- Factory bean that creates the Mongo instance --> 
    <bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean"> 
     <property name="host" value="localhost" /> 
    </bean> 

    <!-- MongoTemplate for connecting and quering the documents in the database --> 
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> 
     <constructor-arg name="mongo" ref="mongo" /> 
     <constructor-arg name="databaseName" value="tableName" /> 
    </bean> 

    <!-- Use this post processor to translate any MongoExceptions thrown in @Repository annotated classes --> 
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 



    <bean id="jspViewResolver" 
      class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
      p:prefix="/WEB-INF/jsp/" 
      p:suffix=".jsp" /> 

    <!-- <bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver"/> 

    <bean class= 
    "org.springframework.web.servlet.view.tiles2.TilesConfigurer"> --> 
<!-- <property name="definitions"> 
    <list> 
     <value>/WEB-INF/views/views.xml</value> 
    </list> 
    </property> 
</bean> --> 




</beans> 

Ecco come il mio web.xml assomiglia

<web-app> 

<!-- <display-name>Archetype Created Web Application</display-name> --> 

    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <!-- <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>/src/main/webapp/WEB-INF/dispatcher-servlet.xml</param-value> 
     </init-param>--> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

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

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> 
    </context-param> 

    <!-- <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> --> 

    <welcome-file-list> 
     <welcome-file>/fileName.jsp</welcome-file> 
    </welcome-file-list> 


</web-app> 

Ok. Funziona quando ho spostato l'intera cartella jsp da /webapp/WEB-INF/jsp/fileName.jsp a /webapp/jsp/fileName.jsp. Mi piacerebbe sapere 1. perché funziona ora? 2. È questo il modo corretto di fare le cose? 3. Funziona quando l'url è localhost: 8080/CtxtRoot/jsp/o localhost: 8080/CtxtRoot/jsp/search.jsp, ma non funziona con localhost: 8080/AnnaUnivResults/jsp/search. Perché è così?

+1

Penso che la capitalizzazione possa effettivamente fare la differenza qui, dato che la primavera sta interpretando le cose in un percorso file. – msknapp

+0

si prega di lasciare un commento che dice se il primo esempio funziona quando il file di benvenuto ha un jsp in minuscolo. – msknapp

+0

Un '' è ** completamente ** non correlato a Spring 'ViewResolver'. La tua domanda è attualmente dappertutto. Dovrai chiarire il tuo percorso di contesto e la richiesta HTTP esatta che invii in ogni scenario. Se la richiesta è gestita da 'DispatcherServlet' di Spring, sarà necessario mostrare anche il gestore. –

risposta

17

Penso che ci siano un paio di problemi qui:

  1. si sono confusi circa i percorsi con Spring MVC
  2. non si sta configurando Web XML correttamente

purtroppo non posso Coprire ogni dettaglio per te, un sacco di primavera è configurabile, quindi la mia spiegazione coprirà solo lo scenario più semplice. Se qualcuno trova un errore, per favore dillo e io lo aggiusterò.

Per i percorsi, potrebbe aiutare a pensare a cose passo dopo passo.

  1. si richiede l'URL dal vostro browser, il browser guarda il protocollo, padrone di casa, e la porta, e utilizza un DNS per trovare l'indirizzo IP corretto per la connessione con.
  2. Viene stabilita una connessione tra il browser e l'host. L'host cerca un processo in esecuzione sulla porta specificata e, se una connessione TCP è consentita da qualsiasi sistema di sicurezza, la richiesta viene trasmessa in streaming al processo in esecuzione su quella porta, il server web.
  3. Il server web prende decisioni sulla base di ciò che è dopo il porto, in particolare, si determina ciò che il contesto dell'applicazione web è guardando il percorso è stato dato. Una volta che determina la root del contesto dell'applicazione, sa quale applicazione web dovrebbe gestire quella richiesta. La decisione è basata su come si configura il server Web, è possibile che un'applicazione Web gestisca richieste senza root di contesto o una specifica root di contesto. Ad esempio, se hai richiesto localhost:8080/CtxtRoot/jsp/, potresti avere un'applicazione web sul server la cui root di contesto è "CtxtRoot" e gestirà tale richiesta. In alternativa, potresti avere un'applicazione con "" per un contesto, e potrebbe gestire quella richiesta. Dipende da come si configura il server, per impostazione predefinita Tomcat utilizzerà il nome della guerra come root di contesto.
  4. L'applicazione Web riceve la richiesta. Mentre conosce l'URL completo richiesto, prende le decisioni solo in base a tutto ciò che segue la root di contesto. Quindi, ad esempio, con la richiesta a localhost:8080/CtxtRoot/jsp/, l'applicazione Web instraderà le cose in base a "jsp" come percorso.
  5. L'applicazione Web ha una catena di filtri che invia prima la richiesta. Se il modello di un filtro corrisponde alla richiesta, tale filtro può valutare la richiesta. Potrebbe bloccare la richiesta, gestire la richiesta o trasmetterla. Non dirò altro perché la tua domanda non riguarda i filtri.
  6. La web app cerca una risorsa il cui modello corrisponde alla richiesta, si considera servlet prima, e poi risorse statiche. La parte URL che viene dopo il contesto è quello che cerca di far corrispondere, quindi, se la richiesta era per localhost:8080/CtxtRoot/jsp/, e la radice contesto era 'CtxtRoot', quindi l'applicazione web è confrontare '/ jsp /' a tutte le mappature servlet. Le richieste di risorse statiche in WEB-INF verranno sempre rifiutate, ma servlet e filtri possono restituire dati da WEB-INF.
  7. ho intenzione di procedere assumendo che la richiesta è stata inviata al DispatcherServlet primavera, riceve la richiesta, e considera tutto ciò che dopo il percorso servlet. Spring's DispatcherServlet cerca un controller il cui percorso corrisponda al percorso dopo il percorso del servlet. Il percorso servlet è sostanzialmente quello che inserisci nella mappatura servlet nel tuo web xml. Lasciatemi fare un esempio, diciamo che hai un'app web il cui contesto è 'app', e ha un servlet MVC di primavera il cui mapping servlet è '/ mvc', e un controller che gestisce il percorso 'vendite', quindi potresti raggiungere quel controller con http://localhost:8080/app/mvc/sales.
  8. Se il DispatcherServlet non riesce a trovare un controller, credo che tratta la richiesta in arrivo come se fosse stato restituito da un controller, quindi se il sub-percorso è 'vendite', allora sarebbe passata che come argomento per il resolver vista . Se non riesce a trovarlo, il server restituisce un errore non trovato.
  9. In genere il controller restituisce una stringa al termine, ovvero il percorso di una risorsa. Potrebbe restituire "popolare" come stringa. Spring inoltra quindi a ViewResolver e supporrò che tu stia utilizzando InternalResourceViewResolver. Osserverà il prefisso e il suffisso e fondamentalmente avvolgerà quelli attorno a ciò che è stato dato. Quindi se il prefisso è '/ WEB-INF/views /', il suffisso è '.jsp', e l'argomento è 'popolare', quindi cercherà una risorsa in '/WEB-INF/views/popular.jsp '. È letteralmente solo concatenare quelle stringhe per fare un percorso. Il percorso è SEMPRE relativo alla radice dell'applicazione Web qui. Se il percorso prodotto è un file jsp, verrà interpretato prima di essere restituito.
  10. Quindi viene infine restituito all'utente.

dal vostro esempio si stavano chiedendo localhost: 8080/ContextRoot/jsp/nome del file, in modo che appaia come 'CtxRoot' è la radice contesto, il percorso del servlet è '/', quindi dovrebbe passare tutto ciò che è dopo che a un controller. Nel momento in cui DispatcherServlet riceve la richiesta, sta cercando un controller che gestisca 'jsp' come percorso. Dal momento che non ne hai avuto, ha deciso di trattarlo come un percorso di risorse. Ha usato il risolutore di viste e formato il percorso /WEB-INF/jsp/jsp/fileName.jsp, che ovviamente non esiste.

Supponiamo che tu avessi invece richiesto localhost: 8080/ContextRoot/fileName, la richiesta avrebbe raggiunto il DispatcherServlet, non avrebbe trovato alcun controller che gestisse 'fileName' come un percorso, e quindi lo tratterebbe come una risorsa. Dovrebbe formare il percorso /WEB-INF/jsp/fileName.jsp, e ciò restituirebbe il risultato.

Tuttavia, il Web XML non è stato configurato per inizializzare la molla. Quindi la tua applicazione web stava effettivamente trattando ognuna delle tue richieste come se fossero per una risorsa relativa alla root dell'applicazione web. Credo che se avessi fatto quella richiesta con Spring correttamente inizializzata, avrebbe funzionato.

Ecco un buon esempio di come farlo:

http://www.mkyong.com/spring3/spring-3-mvc-hello-world-example/

avviso che il suo Web XML ha un ContextLoaderListener, che viene commentata nel tuo, ed è essenziale per l'inizializzazione primavera in una web app . Vedo anche il commento nel tuo dispatcher con il percorso/src/main/resources, ma tutti i percorsi nel web xml dovrebbero essere relativi alla root dell'applicazione web. Al momento dell'esecuzione, il server Web non è a conoscenza del tuo progetto e 'src' non è una directory nella root della tua web app. Si noti inoltre che è possibile avere un contesto applicativo diverso per il materiale MVC rispetto al contesto principale della primavera, e questo è comune.

Credo che se si fanno queste cose che funzionerà:

  1. Spostare il jsp per /WEB-INF/jsp/fileName.jsp
  2. Aggiorna la tua app contesto cosi '/ WEB-INF/jsp/'è il prefisso e' .jsp 'è il suffisso.
  3. Aggiungere il listener del caricatore di contesto al file XML Web e impostare il percorso contextConfigLocation relativo alla root del contesto dell'app. Ad esempio, potrebbe essere /WEB-INF/appContext.xml
  4. fare una richiesta al

    localhost: 8080/CtxtRoot/filename

Inoltre, si continuava a parlare l'accoglienza file , ma stavi dando percorsi completi alle risorse. Il file di benvenuto entra in gioco solo se l'utente effettua una richiesta alla radice di una directory, in questo modo:

localhost:8080/CtxtRoot/ 

Tale richiesta sarà trasmessa al welcome-file. Penso che l'unica volta che l'hai provato, il jsp si trovava nella root della tua app e fosse configurato come file di benvenuto, quindi ha funzionato. Mentre ha "funzionato", NON ha effettivamente usato la molla per restituirlo.

Buona fortuna a te.

+1

+1 per la risposta lunga – dieend

+1

Amico, grazie mille per lo sforzo e il tempo di spiegare questo. Hai acceso una mente analfabeta di primavera. Molto ben spiegato Ho alcune domande 1) La radice di un progetto e la guerra sono sempre '/'? 2) Come posso modificare la root di contesto di un'applicazione nel server tomcat? (Solo per curiosità) 3) Dalla tua spiegazione generale del flusso di lavoro, è sempre un URL a colpire prima dispatcher-servlet.xml e poi a web.xml? (Si tratta di una frase corretta, in caso contrario, riformulare/correggere la risposta) – user3705478

+0

4) Posso usare sia UrlBasedViewResolver che InternalResourceViewResolver in dispatcher-servlet.xml (perché sto usando i pannelli Apache)? 5) Hai menzionato nel punto 6 "Il percorso servlet è in pratica quello che inserisci nella mappatura servlet nel tuo web xml. Lasciatemi fare un esempio, diciamo che hai un'app web il cui contesto è" app "e che ha un spring MVC servlet il cui servlet mapping è '/ mvc'. ", Cosa intendi per" spring MVC servlet il cui mapping servlet è '/ mvc' "? Potresti fornire il codice per il caso che stavi spiegando/mvc. – user3705478

-3

Tutto ciò che è esterno a WEB-INF è pubblicamente disponibile, non viene applicata alcuna autenticazione (possiamo applicare definendo il limite di scurity in web.xml), ma tutte le risorse all'interno di WEB-INF sono protette. È possibile mantenere pagine statiche all'esterno di WEB-INF e pagine dinamiche come profili, account all'interno di WEB-INF. Si prega di verificare che potrei sbagliarmi.

+0

normalmente avresti ragione, ma dal momento che sta usando Spring MVC, spring è in grado di mostrare i file jsp all'interno di web-inf, e in realtà è fatto molto nei loro esempi. Spring ha un filtro che intercetta la richiesta e determina da dove ottenere la vista. Il suo risolutore di vista è configurato per ottenerlo da web-inf, che è perfettamente a posto dato che l'accesso sta arrivando attraverso il filtro, in altre parole, non è accessibile direttamente dalla richiesta http. – msknapp

+0

OP non ha effettuato l'accesso a nulla al di fuori di 'WEB-INF'. –

Problemi correlati