简体   繁体   中英

Spring POST request shows a 404 error page with spring security

I have a little problem with Spring Web that I don't know how to solve. The Get method works (the jps page is showed). When I submit the form I obtain a 404 error page. I putted a breakpoint in my POST method of my controler but the program never stops there.

Do you have an idea on what's wrong ?

PS : I'm using Apache tiles. I don't know if it's important to mention.

Here is my Controller :

package com.kniapps.seotools.controller.keywordranking;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kniapps.seotools.model.Site;
import com.kniapps.seotools.service.ISitesService;

@Controller
public class WebsitesController {


    @Autowired
    private ISitesService sitesService;

    @RequestMapping(value="keyword-ranking/websites", method=RequestMethod.GET)
    public String showWebsitesList(Model model){

        // Get Websites list for current user
        List<Site> liste = sitesService.searchSites();

        // Add list to the model
        model.addAttribute("websitesList",liste);

        return "keyword-ranking/websites";
    }

    @RequestMapping(value="keyword-ranking/websites", method=RequestMethod.POST)
    public String addNewWebsite(@RequestParam("name") String sName,@RequestParam("url") String sURL,@RequestParam("category") String sCategory,@RequestParam("keywords") String sKeywords,Model model){

        model.addAttribute("name",sName);

        return "keyword-ranking/websites";
    }

    public ISitesService getSitesService() {
        return sitesService;
    }

    public void setSitesService( ISitesService sitesService ) {
        this.sitesService = sitesService;
    }

}

My jsp page :

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>

<div class="row">
    <div class="col-lg-12">
        <h1 class="page-header">Websites - Keyword Ranking</h1>
    </div>
    <!-- /.col-lg-12 -->
</div>


<div class="row">
        <div class="col-lg-9">
            <div class="panel panel-default">
                <div class="panel-heading">
                    Websites list
                    <div class="pull-right">
                        <button class="btn btn-default btn-s" data-target="#modal_add_site" data-toggle="modal"><i class="fa fa-plus"></i></button>
                        <button class="btn btn-default btn-s" onclick="OpenDialog();"><i class="fa fa-plus-square"></i></button>
                    </div>
                </div>
                <!-- /.panel-heading -->
                <div class="panel-body">
                    <div class="dataTable_wrapper">
                        <table class="table table-striped table-hover" id="datatable-websites">
                            <thead>
                                <tr>
                                    <th>Name</th>
                                    <th>URL</th>
                                    <th>Category</th>
                                </tr>
                            </thead>
                            <tbody>
                                <c:forEach var="i" begin="0" end="${fn:length(websitesList)-1}">
                                    <tr class="odd gradeX">
                                        <td>
                                            <a href="<c:url value="/keyword-ranking/site?id=${websitesList[i].id}"/>"><c:out value="${websitesList[i].name}"/></a> - 
                                            <a href="#"><i class="fa fa-pencil-square-o fa-fw"></i></a>
                                            <a href="#"><i class="fa fa-trash-o fa-fw"></i></a>
                                        </td>
                                        <td><a href="${websitesList[i].url}" target="_blank"><c:out value="${websitesList[i].url}"/></a></td>
                                        <td><c:out value="jeux"/></td>
                                    </tr>
                                </c:forEach>

                            </tbody>
                        </table>
                    </div>
                    <!-- /.table-responsive -->

                </div>
                <!-- /.panel-body -->
            </div>
            <!-- /.panel -->


            <!-- Modal -->           
            <div style="display: none;" class="modal fade" id="modal_add_site" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                    <div class="modal-content">
                    <form role="form" id="form_add_website" method="POST" action="<c:url value="/keyword-ranking/websites"/>">

                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                            <h4 class="modal-title" id="myModalLabel">Add a new website</h4>
                        </div>
                        <div class="modal-body">

                               <div class="form-group input-group">     
                                   <input class="form-control" id="name" name="name" placeholder="Site name" type="text"/>
                                   <span class="input-group-addon">Name</span>
                               </div>
                               <div class="form-group input-group">     
                                   <input class="form-control" id="url" name="url" placeholder="http://" type="text"/>
                                   <span class="input-group-addon">URL</span>
                               </div>
                               <div class="form-group input-group">                                     
                                    <input class="form-control" list="list_keywords" id="category" name="category" placeholder="type a new category on select one"/>
                                    <span class="input-group-addon">Category</span> 
                                    <datalist id="list_keywords">
                                      <option value="jeux">
                                      <option value="test">
                                      <option value="test1">
                                      <option value="test2">
                                      <option value="test3">
                                    </datalist>                                               
                               </div>
                               <div class="form-group input-group">                    
                                   <textarea class="form-control" rows="3" placeholder="keyword1,keyword2,keyword3..." id="keywords"  name="keywords" ></textarea>
                                   <span class="input-group-addon">Keywords</span>
                               </div>                

                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                            <button type="submit" class="btn btn-primary">Add</button>
                        </div>

                    </form>
                    </div>
                    <!-- /.modal-content -->
                </div>
                <!-- /.modal-dialog -->
            </div>
            <!-- /.modal -->

        </div>
        <!-- /.col-lg-12 -->
    </div>


    <script>
    $(document).ready(function() {      

        // If URL contain "#addWebsite" THEN AddWebsite dialog is showed
        if(window.location.href.indexOf("#addWebsite",0) > 0) $('#modal_add_site').modal('show');  

        // Datatable config
        $('#datatable-websites').DataTable({
                responsive: true
        }); 


    });
    </script>

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">

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

    <!-- Spring Servlet + Mapping -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

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

    <!-- Tiles -->
    <listener>
        <listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
    </listener>

    <!-- Loads Spring Security / Database config file -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-security.xml,
            /WEB-INF/spring-database.xml
        </param-value>
    </context-param>

    <!-- Spring Security -->
    <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>

</web-app>

dispatcher-servlet.xml :

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

    <!-- Scan for ressources -->
    <context:component-scan base-package="com.kniapps.seotools" />

    <!-- Annotations -->
    <tx:annotation-driven/>

    <!-- Using Tiles -->
    <bean   
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">  
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />  
    </bean>

    <bean id="tilesConfigurer"  
        class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">  
        <property name="definitions">  
            <list>  
                <value>/WEB-INF/tiles.xml</value>  
            </list>  
        </property>  
    </bean>

    <!-- Ressources Search -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>  JSTL -->
        <property name="prefix">
            <value>/WEB-INF/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

    <!-- Internalisation -->
    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>

    <!-- Resource files : CSS, JS... -->
    <mvc:resources mapping="/resources/**" location="/resources/theme_default/" cache-period="31556926"/>
    <mvc:annotation-driven />

</beans>

Console :

09:00:30.741 [http-bio-8080-exec-4] DEBUG org.hibernate.loader.Loader - Result set row: 0
09:00:30.741 [http-bio-8080-exec-4] DEBUG org.hibernate.loader.Loader - Result row: EntityKey[com.kniapps.seotools.model.SearchEngine#1]
09:00:30.741 [http-bio-8080-exec-4] DEBUG o.h.engine.internal.TwoPhaseLoad - Resolving associations for [com.kniapps.seotools.model.SearchEngine#1]
09:00:30.741 [http-bio-8080-exec-4] DEBUG o.h.engine.internal.TwoPhaseLoad - Done materializing entity [com.kniapps.seotools.model.SearchEngine#1]
09:00:30.781 [http-bio-8080-exec-4] DEBUG org.hibernate.loader.Loader - Done entity load
09:00:30.781 [http-bio-8080-exec-4] DEBUG o.h.engine.internal.TwoPhaseLoad - Done materializing entity [com.kniapps.seotools.model.Site#1]
09:00:30.781 [http-bio-8080-exec-4] DEBUG o.h.engine.internal.TwoPhaseLoad - Resolving associations for [com.kniapps.seotools.model.Site#2]
09:00:30.781 [http-bio-8080-exec-4] DEBUG o.h.engine.internal.TwoPhaseLoad - Done materializing entity [com.kniapps.seotools.model.Site#2]
09:00:30.821 [http-bio-8080-exec-4] DEBUG o.s.o.h.HibernateTransactionManager - Initiating transaction commit
09:00:30.821 [http-bio-8080-exec-4] DEBUG o.s.o.h.HibernateTransactionManager - Committing Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.kniapps.seotools.model.Site#1], EntityKey[com.kniapps.seotools.model.SearchEngine#1], EntityKey[com.kniapps.seotools.model.Site#2]],collectionKeys=[CollectionKey[com.kniapps.seotools.model.Site.keywords#2], CollectionKey[com.kniapps.seotools.model.Site.notes#2], CollectionKey[com.kniapps.seotools.model.Site.notes#1], CollectionKey[com.kniapps.seotools.model.Site.keywords#1]]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]
09:00:30.821 [http-bio-8080-exec-4] DEBUG o.h.e.t.spi.AbstractTransactionImpl - committing
09:00:30.861 [http-bio-8080-exec-4] DEBUG o.h.e.t.i.jdbc.JdbcTransaction - committed JDBC Connection
09:00:30.861 [http-bio-8080-exec-4] DEBUG o.h.e.t.i.jdbc.JdbcTransaction - re-enabling autocommit
09:00:30.931 [http-bio-8080-exec-4] DEBUG o.s.jdbc.datasource.DataSourceUtils - Resetting read-only flag of JDBC Connection [jdbc:mysql://mysql-ogamewin.alwaysdata.net:3306/ogamewin_seo, UserName=ogamewin@85.0.255.156, MySQL Connector Java]
09:00:30.931 [http-bio-8080-exec-4] DEBUG o.s.o.h.HibernateTransactionManager - Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.kniapps.seotools.model.Site#1], EntityKey[com.kniapps.seotools.model.SearchEngine#1], EntityKey[com.kniapps.seotools.model.Site#2]],collectionKeys=[CollectionKey[com.kniapps.seotools.model.Site.keywords#2], CollectionKey[com.kniapps.seotools.model.Site.notes#2], CollectionKey[com.kniapps.seotools.model.Site.notes#1], CollectionKey[com.kniapps.seotools.model.Site.keywords#1]]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction
09:00:30.931 [http-bio-8080-exec-4] DEBUG o.h.e.j.i.LogicalConnectionImpl - Releasing JDBC connection
09:00:30.931 [http-bio-8080-exec-4] DEBUG o.h.e.j.i.LogicalConnectionImpl - Released JDBC connection
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'keyword-ranking/websites'
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.s.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.tiles3.TilesView: name 'keyword-ranking/websites'; URL [keyword-ranking/websites]] in DispatcherServlet with name 'dispatcher'
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.s.w.servlet.view.tiles3.TilesView - Added model object 'websitesList' of type [java.util.ArrayList] to request in view with name 'keyword-ranking/websites'
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'requestDataValueProcessor'
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.a.tiles.impl.BasicTilesContainer - Render request received for definition 'keyword-ranking/websites'
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'requestDataValueProcessor'
09:00:30.941 [http-bio-8080-exec-4] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'requestDataValueProcessor'
09:00:30.991 [http-bio-8080-exec-4] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
09:00:30.991 [http-bio-8080-exec-4] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
09:00:30.991 [http-bio-8080-exec-4] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
09:00:44.053 [http-bio-8080-exec-5] DEBUG o.s.security.web.FilterChainProxy - /keyword-ranking/websites at position 1 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
09:00:44.053 [http-bio-8080-exec-5] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@4432a202: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4432a202: Principal: org.springframework.security.core.userdetails.User@2dba1e: Username: alex; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@21a2c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: B56363754FD9534CE1CF07FFF79E416B; Granted Authorities: ROLE_USER'
09:00:44.053 [http-bio-8080-exec-5] DEBUG o.s.security.web.FilterChainProxy - /keyword-ranking/websites at position 2 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
09:00:44.053 [http-bio-8080-exec-5] DEBUG o.s.security.web.FilterChainProxy - /keyword-ranking/websites at position 3 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
09:00:44.053 [http-bio-8080-exec-5] DEBUG o.s.security.web.csrf.CsrfFilter - Invalid CSRF token found for http://localhost:8080/kniseotools/keyword-ranking/websites
09:00:44.063 [http-bio-8080-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcher' processing POST request for [/kniseotools/403]
09:00:44.063 [http-bio-8080-exec-5] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /403
09:00:44.063 [http-bio-8080-exec-5] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Did not find handler method for [/403]
09:00:44.063 [http-bio-8080-exec-5] WARN  o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/kniseotools/403] in DispatcherServlet with name 'dispatcher'
09:00:44.063 [http-bio-8080-exec-5] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
09:00:44.063 [http-bio-8080-exec-5] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

Request headers :

POST /kniseotools/keyword-ranking/websites HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 30
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:8080/kniseotools/keyword-ranking/websites
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: JSESSIONID=B216EFC289A5A5445872B4832167BCDC

Response :

<html><head><title>Apache Tomcat/7.0.62 - Rapport d''erreur</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>Etat HTTP 404 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Rapport d''état</p><p><b>message</b> <u></u></p><p><b>description</b> <u>La ressource demandée n''est pas disponible.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.62</h3></body></html>

SOLUTION FOUND :

I use spring security. PLease disable csrf protection in the security xml file by removing this :

<!-- enable csrf protection -->
        <csrf />

Thanks for your help

The error is that the name attribute is missing in your imput.

The name attribute specifies the name which the parameters are sent to the server.

You can check by looking in your console exception: MissingServletRequestParameterException : Required String parameter 'name' is not present

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM