2014-07-10 10 views
13

Ich bin dieses Problem in Bezug auf JSP nicht PUT Anfrage zu akzeptieren. Ich frage mich, wie ich das beheben kann. Ich habe diese verwandte Frage im Stapelüberlauf gelesen, aber es erklärt nicht, wie man es repariert.405 JSP Fehler mit Put-Methode

HTTP Status 405 - JSPs only permit GET POST or HEAD

Von Rails Hintergrund, ich versuche, es zu machen, so verwende ich die Schienen REST-Stil wie PUT für Updates und DELETE für Löschungen der Benutzerressource.

Wenn jedoch ein Fehler in diesem Controller auftritt, wird versucht, die Anforderung an die ursprüngliche JSP zurückzugeben, aber Tomcat 8.0.9 akzeptiert die Anforderung nicht und gibt folgenden Fehler aus: "HTTP-Status 405 - JSPs erlauben nur GET POST oder KOPF". Ich habe versucht, readonly in der Tomcat web.xml zu deaktivieren - es hatte keinen Effekt und ich bekomme immer noch den Fehler. Ich habe es auf POST-Methode umgestellt und der Ablauf funktioniert gut.

Gibt es eine Möglichkeit, die Forward-POST-Methode zu erzwingen und trotzdem die PUT-Methode für die Anforderung zu akzeptieren?

/** 
    * Edit a user account. 
    * @return the edit user view 
    */ 
    @RequestMapping(value = {"/update/{userId}"}, method = RequestMethod.PUT) 
    public String updateUser(@Valid @ModelAttribute("user") User user, BindingResult result, final RedirectAttributes redirectAttributes) 
    { 
     logger.debug(user); 

     // we check for duplicate email addresses during the update operation. 
     List<User> userCheckList = userRepository.findByEmail(user.getEmail()); 
     if (userCheckList.size() > 0) 
     { 
      // size of list should only ever be 1 
      User userCheck = userCheckList.get(0); 
      if (userCheck.getId() != user.getId()) 
      { 
       result.rejectValue("email", "error.user", "An account already exists for this user email address."); 
      } 
     } 


     if (result.hasErrors()) 
     { 
      return "admin.users.edit"; 
     } 

     // we locate the user and add it to the model 
     userRepository.save(user); 



     // the save operation was successful so we show the user message. 
     redirectAttributes.addFlashAttribute("user", user); 
     redirectAttributes.addFlashAttribute("message", "Updated successfully"); 


     String viewName = "redirect:/admin/users"; 
     logger.debug(viewName); 

     return viewName; 
    } 
+0

das kann Ihnen helfen http://www.codereye.com/2010/12/configure-tomcat-to-accept-http-put.html – mahesh

+0

danke ich habe das schon versucht, aber es hatte keine Wirkung, gleich Fehler passiert. –

Antwort

15

Das Problem ist, dass, wenn Sie einen Ansichtsnamen von Ihrer Controller-Methode zurückkehren, der Frühling DispatcherServlet einen nach vorn auf die gegebene Ansicht tun wird, die ursprünglichen PUT Verfahren erhalten.

Bei dem Versuch, dies weiterzuleiten, wird Tomcat es ablehnen, mit der Begründung, dass eine PUT zu einer JSP so verstanden werden könnte, "diese JSP-Datei auf dem Server mit dem Inhalt dieser Anfrage zu ersetzen".

Wirklich möchten Sie Ihren Controller Ihre PUT Anfragen behandeln und dann zu Ihren JSPs als GET weiterleiten. Glücklicherweise bietet Servlet 3.0 eine Möglichkeit, rein auf den FORWARD Dispatcher zu filtern.

Erstellen Sie einen Filter:

public class GetMethodConvertingFilter implements Filter { 

    @Override 
    public void init(FilterConfig config) throws ServletException { 
     // do nothing 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
     throws IOException, ServletException { 

     chain.doFilter(wrapRequest((HttpServletRequest) request), response); 
    } 

    @Override 
    public void destroy() { 
     // do nothing 
    } 

    private static HttpServletRequestWrapper wrapRequest(HttpServletRequest request) { 
     return new HttpServletRequestWrapper(request) { 
      @Override 
      public String getMethod() { 
       return "GET"; 
      } 
     }; 
    } 
} 

Und Draht in Ihre web.xml thusly:

<filter> 
    <filter-name>getMethodConvertingFilter</filter-name> 
    <filter-class>my.GetMethodConvertingFilter</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>getMethodConvertingFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping> 

Dies wird auf Vorwärts nur Anfragen an GET konvertieren, unverändert Anfragen durch andere Disponenten verlassen, so PUT s wird von Ihren Controllern wie üblich abgefangen.

Mein (möglicherweise inkorrektes) Verständnis ist, dass Tomcat 8.0.9 einen Fix eingeführt hat, wo dies effektiv automatisch für den Dispatcher durchgeführt wird - siehe answer in Ihrer verknüpften Frage. Aber Sie verwenden nicht den Fehlerbehandlungsmechanismus des Containers, um Ihre Fehlerseite zu rendern, Sie verwenden Spring MVC, um manuell zur Ansicht weiterzuleiten, weshalb Sie dies tun müssen. Persönlich stieß ich auf dieses Problem unter Jetty 9.2.7, wo keine solche Korrektur vorhanden ist, und ich delegiere die Fehlerbehandlung an den Container, so dass ich <dispatcher>ERROR</dispatcher> auch in meiner Filterzuordnung konfiguriert habe.

Das alles scheint ein wenig geheimnisvoll, aber ist die einzige Möglichkeit, die ich durch diesen speziellen RESTful-Spring-JSP-Web-Anwendung-Hoop erfolgreich springen konnte.

+0

Danke Ich habe es geschafft, alles auf Post zu setzen, es ist nicht so eine große Sache, Post v Put zu verwenden. Ich habe mich gefragt, ob es eine Möglichkeit gibt, zurück zu der neuen Methode umzuleiten, obwohl es einen Fehler gibt, während das BindingResult für die Anfrage verfügbar bleibt, das würde es zurück zu GET leiten und für meinen Code besser sein. Ich habe es jedoch noch nicht so gründlich untersucht. Diese Antwort ist jedoch eine gute Lösung, also werde ich es richtig markieren. –

1

hatte ich das gleiche Problem und löste es am Ende von

<%@ page isErrorPage="true" %> 

am Anfang meiner JSP-Seite hinzufügen.
Mit Apache-Jsp-8.0.33, org/apache/jasper/compiler/Generator.java überspringt die Erstellung dieser Überprüfung für Seiten, für die dieses Flag gesetzt ist, sodass die JSP auf jede Methode antworten kann.

Verwandte Themen