HTTP Status 405 - Request method 'PUT' not supported

三世轮回 提交于 2020-04-06 02:27:47

问题


I have the following controller:

@RestController
public class RestaurantController {
    @Autowired
    RestaurantService restaurantService;
    @RequestMapping(value = "/restaurant/", method = RequestMethod.GET)
    public ResponseEntity<List<Restaurant>> listAllRestaurants() {
        System.out.println("Fetching all restaurants");
        List<Restaurant> restaurants = restaurantService.findAllRestaurants();
        if(restaurants.isEmpty()){
            return new ResponseEntity<List<Restaurant>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
        }
        return new ResponseEntity<List<Restaurant>>(restaurants, HttpStatus.OK);
    }
    @RequestMapping(value = "/restaurant/{id}", method = RequestMethod.PUT)
    public ResponseEntity<Restaurant> updateRestaurant(@PathVariable("id") int id, @RequestBody Restaurant restaurant) {
        System.out.println("Updating Restaurant " + id);

        Restaurant currentRestaurant = restaurantService.findById(id);

        if (currentRestaurant==null) {
            System.out.println("Restaurant with id " + id + " not found");
            return new ResponseEntity<Restaurant>(HttpStatus.NOT_FOUND);
        }

        currentRestaurant.setName(restaurant.getName());
        currentRestaurant.setDescription(restaurant.getDescription());
        currentRestaurant.setIcon(restaurant.getIcon());

        restaurantService.updateRestaurant(currentRestaurant);
        return new ResponseEntity<Restaurant>(currentRestaurant, HttpStatus.OK);
    }
}

Here is my calls from the PostMan. First I am making the GET call to get all the restaurants and it works fine Second I am trying to update the object by I am getting the following error. At the Tomcat 8.0.32, I am getting the following log:

13-Feb-2016 16:55:09.442 WARNING [http-apr-8080-exec-9] org.springframework.web.servlet.PageNotFound.handleHttpRequestMethodNotSupported Request method 'PUT' not supported

I don't understand this is how possible. And here is my dependencies:

<properties>
        <springframework.version>4.1.6.RELEASE</springframework.version>
        <springsecurity.version>4.0.1.RELEASE</springsecurity.version>
        <hibernate.version>4.3.6.Final</hibernate.version>
        <mysql.connector.version>5.1.31</mysql.connector.version>
        <jackson.version>2.6.3</jackson.version>
        <joda-time.version>2.3</joda-time.version>
        <testng.version>6.9.4</testng.version>
        <mockito.version>1.10.19</mockito.version>
        <h2.version>1.4.187</h2.version>
        <dbunit.version>2.2</dbunit.version>
    </properties>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- jsr303 validation -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.3.Final</version>
        </dependency>

        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>

        <!-- Joda-Time -->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>${joda-time.version}</version>
        </dependency>

        <!-- To map JodaTime with database type -->
        <dependency>
            <groupId>org.jadira.usertype</groupId>
            <artifactId>usertype.core</artifactId>
            <version>3.0.0.CR1</version>
        </dependency>
        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${springsecurity.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${springsecurity.version}</version>
        </dependency>
        <!-- Servlet+JSP+JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- Need this for json to/from object -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <!-- Testing dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${springframework.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>dbunit</groupId>
            <artifactId>dbunit</artifactId>
            <version>${dbunit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

If more information is needed please tell me! Thanks.

Edit 1:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("bill").password("user").roles("USER");
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("dba").password("dba").roles("ADMIN","DBA");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

      http.authorizeRequests()
        .antMatchers("/", "/home","/restaurant/**").permitAll()
        .antMatchers("/list").access("hasRole('USER')")
        .antMatchers("/list").access("hasRole('ADMIN')")
        .antMatchers("/admin/**").access("hasRole('ADMIN')")
        .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
        .and().formLogin().loginPage("/login")
        .usernameParameter("ssoId").passwordParameter("password")
        .and().csrf()
        .and().exceptionHandling().accessDeniedPage("/Access_Denied");
    }
}

Edit 2:

2016-02-14 12:30:56 DEBUG FilterChainProxy:324 - /restaurant/1 at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'

2016-02-14 12:30:56 DEBUG FilterChainProxy:324 - /restaurant/1 at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'

2016-02-14 12:30:56 DEBUG HttpSessionSecurityContextRepository:159 - No HttpSession currently exists

2016-02-14 12:30:56 DEBUG HttpSessionSecurityContextRepository:101 - No SecurityContext was available from the HttpSession: null. A new one will be created.

2016-02-14 12:30:56 DEBUG FilterChainProxy:324 - /restaurant/1 at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'

2016-02-14 12:30:56 DEBUG HstsHeaderWriter:128 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3ded3d8a

2016-02-14 12:30:56 DEBUG FilterChainProxy:324 - /restaurant/1 at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'

2016-02-14 12:30:56 DEBUG CsrfFilter:106 - Invalid CSRF token found for http://localhost:8080/SpringSecurityCusotmLoginFormAnnotationExample/restaurant/1

2016-02-14 12:30:56 DEBUG DispatcherServlet:861 - DispatcherServlet with name 'dispatcher' processing PUT request for [/SpringSecurityCusotmLoginFormAnnotationExample/Access_Denied]

2016-02-14 12:30:56 DEBUG RequestMappingHandlerMapping:294 - Looking up handler method for path /Access_Denied

2016-02-14 12:30:56 DEBUG ExceptionHandlerExceptionResolver:134 - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported

2016-02-14 12:30:56 DEBUG ResponseStatusExceptionResolver:134 - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported

2016-02-14 12:30:56 DEBUG DefaultHandlerExceptionResolver:134 - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PUT' not supported

2016-02-14 12:30:56 WARN PageNotFound:198 - Request method 'PUT' not supported

2016-02-14 12:30:56 DEBUG HttpSessionSecurityContextRepository:337 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.

2016-02-14 12:30:56 DEBUG DispatcherServlet:1034 - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling

2016-02-14 12:30:56 DEBUG DispatcherServlet:996 - Successfully completed request

2016-02-14 12:30:56 DEBUG DefaultListableBeanFactory:248 - Returning cached instance of singleton bean 'delegatingApplicationListener'

2016-02-14 12:30:56 DEBUG HttpSessionSecurityContextRepository:337 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.

2016-02-14 12:30:56 DEBUG SecurityContextPersistenceFilter:105 - SecurityContextHolder now cleared, as request processing completed


回答1:


Try turning up the logging level for org.springframework.web to DEBUG. This will give you some insight into how Spring is trying to deal with the request. Hopefully, it will give you (or us) some more clues on how to fix it.

If you're using Spring Boot, just add this line to your application.properties file:

logging.level.org.springframework.web=DEBUG

Edit after seeing additional logging:

The 'PUT' not supported message is a bit misleading. The real problem comes before that. You don't have a valid CSRF token. How are you submitting the request? It looks like you are using the PostMan tool (but I am not familiar with this tool) rather than submitting the form directly from a web-page. There may be some way that you can add the token to your request using the tool. Does it work without the tool - submitting the form directly from the web-page?




回答2:


I had the same error but for me it was caused by the fact that I had ommited the ID as URL parameter. I ommited it because the ID was present in the JSON body.

When I changed .../restaurant to ...restaurant/1, the error went away.




回答3:


instead of sending request to /restaurant/1/, send it to /restaurant/1




回答4:


By default, in WebMvcAutoConfiguration, HttpPutFormContentFilter is not configured and hence the issue.

Its fixed in spring boot [1.3.0) version and working fine. So, you may try updating your spring-boot version or configure this filter manually to make things work.

Issue reference.
Another Stackoverlow reference

Hope it helps.




回答5:


If you don't need csrf you can do this.

@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
}

}




回答6:


I think your Model should implement Serializable interface and should have a default constructor.

For me issue was solved by adding above to my Model class and @RequestBody to the Controller method argument.



来源:https://stackoverflow.com/questions/35381402/http-status-405-request-method-put-not-supported

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!