2013-11-22 2 views
6

404 pagine funzionano correttamente sul mio sito per tutte le url a meno che non finiscano in .jsp. In tal caso ottengo la pagina generica jboss 404 invece della mia pagina Spring 404 in stile.Come si fa a fare in modo che gli URL non validi che terminano con .jsp utilizzino la pagina Spring 404?

Ho il seguente nel mio web.xml:

<error-page> 
    <error-code>404</error-code> 
    <location>/WEB-INF/error/404.jsp</location> 
</error-page> 

cura con piena web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 

    <servlet> 
     <servlet-name>mainServlet</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>/WEB-INF/spring/servlet-context.xml</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

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

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

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      /WEB-INF/spring/root-context.xml, 
      /WEB-INF/spring-security.xml 
     </param-value> 
    </context-param> 

    <welcome-file-list> 
     <welcome-file></welcome-file> 
    </welcome-file-list> 

    <filter> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <filter-class> 
      org.springframework.web.filter.DelegatingFilterProxy 
     </filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter> 
     <filter-name>encodingFilter</filter-name> 
     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
     <init-param> 
      <param-name>encoding</param-name> 
      <param-value>UTF-8</param-value> 
     </init-param> 
     <init-param> 
      <param-name>forceEncoding</param-name> 
      <param-value>true</param-value> 
     </init-param> 
    </filter> 

    <filter-mapping> 
     <filter-name>encodingFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <error-page> 
     <error-code>400</error-code> 
     <location>/WEB-INF/error/400.jsp</location> 
    </error-page> 

    <error-page> 
     <error-code>403</error-code> 
     <location>/WEB-INF/error/403.jsp</location> 
    </error-page> 

    <error-page> 
     <error-code>404</error-code> 
     <location>/WEB-INF/error/404.jsp</location> 
    </error-page> 

    <error-page> 
     <error-code>405</error-code> 
     <location>/WEB-INF/error/405.jsp</location> 
    </error-page> 

    <error-page> 
     <exception-type>java.lang.Exception</exception-type> 
     <location>/WEB-INF/error/error.jsp</location> 
    </error-page> 

    <context-param> 
     <param-name>defaultHtmlEscape</param-name> 
     <param-value>true</param-value> 
    </context-param> 
</web-app> 

risposta

3

Il problema è probabilmente che il vostro web.xml sta puntando direttamente sul tuo jsp pagine invece di dirigere verso un controller a molla che può quindi puntare alla vista appropriata.

Sarei curioso di vedere anche il tuo rootContext.xml per vedere come hai impostato il tuo resolver di visualizzazione. Perché forse la primavera si sta confondendo ... Ci sono solo un paio di modi in cui l'App Container (JBoss) finirebbe per gestire l'errore, e cioè se la richiesta non corrisponde nemmeno al servlet di contesto Spring o se non ci sono errori gestore per il tipo di errore generato (è possibile che il tentativo di gestire "asdlfasdf.jsp" finisce per causare un altro tipo di eccezione che non è sempre registrato e quindi è sempre gettato fino a JBoss e trattati come un 404?).

Ma in modo da avere qualcosa da confrontare - Ecco come io ho il mio set up:

Ho una singola pagina error.jsp nel mio indice di vista e istituito il risolutore vista simile al seguente:

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> 
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> 
    <property name="prefix" value="/WEB-INF/views/"/> 
    <property name="suffix" value=".jsp"/> 
</bean> 

Quindi, ho una classe base di PageController che estendo per tutte le altre mie classi di controller "user facing". Questa classe ha un metodo che gestisce i "/ error/404", "/ error/403" errore di stile pagina: modelli

@RequestMapping(value = "/error/{code}") 
public String errorPage(Principal principal, Model model, @PathVariable("code") int code) { 
    model.addAttribute("code", code); 
    return "error"; 
} 

Poi, ho creato il web.xml simile al tuo, solo il reindirizzamento alla endpoint controllore primavera lungo con il codice appropriato:

<error-page> 
    <error-code>404</error-code> 
    <location>/error/404</location> 
</error-page> 

<error-page> 
    <error-code>403</error-code> 
    <location>/error/403</location> 
</error-page> 

Ora, non so se questo è il modo migliore, ma funziona molto bene per me. Il contenitore Web indirizza questi tipi di errore alla/code/code page che sta chiamando semplicemente un metodo controller e quindi il metodo controller produce la pagina error.jsp (restituendo il nome della vista "error").

Poiché inserisce il codice di errore nel modello, ho un singolo jsp che gestisce più tipi di errore, ho appena inserito un condizionale che restituisce un messaggio utente diverso a seconda del codice di errore. In altre parole, "Pagina non trovata :(" vs "Non sei autorizzato a visualizzare questa pagina!"

E quindi faccio questo nella mia configurazione di sicurezza di primavera per assicurarmi che un utente non autenticato possa vedere la pagina di errore (probabilmente avete ottenuto questa parte già dato che è possibile vedere le pagine JSP):

<http pattern="/error/**" security="none" /> 

ho combinare questo con i gestori di eccezioni stile di annotazione di fare tutto il mio eccezione server di gestione (gestione delle richieste di dati con una risposta di errore e jSON html/visualizza richieste con pagine html di errore) perché puoi semplicemente annotare un metodo del controller per gestire Exception o RuntimeException.Mi consiglia di controllare questo metodo come bene perché è molto potente e lo rende notevolmente più semplice per accedere e gestire le eccezioni con garbo:

@ExceptionHandler(Exception.class) 
public ModelAndView exceptionHandler(Exception e){ 
    ModelAndView modelAndView = new ModelAndView(); 
    modelAndView.getModelMap().addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR); 
    modelAndView.setViewName("error"); 

    logger.error("Error handling page request.", e); 
    return modelAndView; 
} 

Questo è anche un buon modo per assicurarsi di avere la possibilità di accedere eccezioni che passano attraverso i controller senza dover inserire la gestione delle eccezioni in ogni singolo.

Ho fatto due classi base ... uno per il mio controller di pagina e uno per i miei titolari del trattamento di riposo. Il controller della pagina di base restituisce la vista jsp che rende una bella pagina di errore per l'utente. Il controller del resto del database di base restituisce un messaggio json con le informazioni di errore nel modello e quindi jsp stamperà lo stack completo o solo un errore generico a seconda che il server sia in esecuzione in modalità di sviluppo o di produzione.

+0

Grazie mille, aggiungendo il controller degli errori anziché il collegamento diretto alle pagine jsp lavorate. – oojoe