Java HTTP状态405-请求方法';把';不支持
我有以下控制器:Java HTTP状态405-请求方法';把';不支持,java,spring,spring-mvc,Java,Spring,Spring Mvc,我有以下控制器: @RestController public class RestaurantController { @Autowired RestaurantService restaurantService; @RequestMapping(value = "/restaurant/", method = RequestMethod.GET) public ResponseEntity<List<Restaurant>> listA
@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);
}
}
编辑2:
2016-02-14 12:30:56调试过滤器ChainProxy:324-/餐厅/1 at
附加过滤器链中的位置1/12;点火过滤器:
“WebAsyncManagerIntegrationFilter”
2016-02-14 12:30:56调试
过滤链氧气:324-/restaurant/1位于附加位置12的第2处
过滤链;正在启动筛选器:“SecurityContextPersistenceFilter”
2016-02-14 12:30:56调试HttpSessionSecurityContextRepository:159-
目前不存在HttpSession
2016-02-14 12:30:56调试
HttpSessionSecurityContextRepository:101-未找到SecurityContext
可从HttpSession获得:null。将创建一个新的
2016-02-14 12:30:56调试过滤器ChainProxy:324-/餐厅/1 at
附加过滤器链中12的位置3;点火过滤器:
“HeaderWriterFilter”
2016-02-14 12:30:56调试HstsHeaderWriter:128-
未注入HSTS标头,因为它与requestMatcher不匹配
org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3ded3d8a
2016-02-14 12:30:56调试过滤器ChainProxy:324-/餐厅/1 at
附加过滤器链中12的位置4;点火过滤器:
“CsrfFilter”
2016-02-14 12:30:56调试CSRF过滤器:106-无效CSRF
为找到令牌
2016-02-14 12:30:56调试DispatcherServlet:861-DispatcherServlet
名为“dispatcher”的处理PUT请求
[/springsecuritycusotmloginformnotationexample/Access\u Denied]
2016-02-14 12:30:56调试请求映射Handler映射:294-正在查找
路径/访问被拒绝的up handler方法
2016-02-14 12:30:56调试
ExceptionHandlerExceptionResolver:134-从解析异常
处理程序[null]:
org.springframework.web.HttpRequestMethodNotSupportedException:
不支持请求方法“PUT”
2016-02-14 12:30:56调试
ResponseStatusExceptionResolver:134-从处理程序解析异常
[null]:
org.springframework.web.HttpRequestMethodNotSupportedException:
不支持请求方法“PUT”
2016-02-14 12:30:56调试
DefaultHandlerExceptionResolver:134-从处理程序解析异常
[null]:
org.springframework.web.HttpRequestMethodNotSupportedException:
不支持请求方法“PUT”
2016-02-14 12:30:56警告
PageNotFound:198-不支持请求方法“PUT”
2016-02-14 12:30:56调试HttpSessionSecurityContextRepository:337-
SecurityContext为空或内容为匿名-上下文不会
存储在HttpSession中
2016-02-14 12:30:56调试
DispatcherServlet:1034-返回到的ModelAndView为空
名为“dispatcher”的DispatcherServlet:假定为HandlerAdapter
已完成请求处理
2016-02-14 12:30:56调试
DispatcherServlet:996-已成功完成请求
2016-02-14 12:30:56调试DefaultListableBeanFactory:248-返回缓存
单例bean“delegatingApplicationListener”的实例
2016-02-14 12:30:56调试HttpSessionSecurityContextRepository:337-
SecurityContext为空或内容为匿名-上下文不会
存储在HttpSession中
2016-02-14 12:30:56调试
SecurityContextPersistenceFilter:105-现在是SecurityContextHolder
已清除,因为请求处理已完成
不要将请求发送到
/restaurant/1/
,而是将其发送到/restaurant/1
尝试将org.springframework.web
的日志记录级别调到DEBUG
。这将让您了解Spring如何处理请求。希望它能为您(或我们)提供更多关于如何修复它的线索
如果您使用的是Spring Boot,只需将这一行添加到application.properties文件:
查看其他日志后进行编辑:
“PUT”不受支持的消息有点误导。真正的问题在那之前。您没有有效的CSRF令牌。您是如何提交请求的?看起来您使用的是邮递员工具(但我不熟悉这个工具),而不是直接从网页提交表单。您可以通过某种方式使用该工具将令牌添加到请求中。在没有工具的情况下是否可以工作?直接从网页提交表单?默认情况下,在
WebMvcAutoConfiguration
中,HttpPutFormContentFilter
未配置,因此出现问题
它在spring boot[1.3.0)
版本中已修复,工作正常。因此,您可以尝试更新spring boot版本或手动配置此筛选器以使其正常工作
.希望能有所帮助。我也有同样的错误,但对我来说,这是因为我将ID作为URL参数进行了修改。之所以修改,是因为该ID存在于JSON正文中
当我将…/restaurant更改为…/restaurant/1时,错误消失了。如果您不需要csrf,您可以这样做
@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}我认为您的模型应该实现可序列化接口,并且应该有一个默认构造函数
对于我来说,通过将上述内容添加到我的模型类中,并将@RequestBody添加到控制器方法参数中,问题得以解决。HTTP 405如果无法反序列化对象,也会返回错误代码,例如,对于没有默认构造函数的对象,会出现这种情况 以这项服务为例:
import javax.ws.rs.*;
import com.sun.jersey.spi.resource.Singleton;
@Singleton
@Path("root")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class SampleRestService { ..
@PUT
@Path("sample")
public void update(Sample whitelist) throws SampleException {
// do some
}
和对象示例,覆盖默认构造函数:
class Sample{
int x,y;
public sample(int x, int y){
// boring stuff
}
}
在这种情况下,解组无法反序列化请求内容,并触发405。或者,这就是glassfish 3.5和javax.ws.rs-api-2.0.1.jar以及jersey-xxx-2.25.1.jar的工作方式
修复方法实际上是将默认构造函数(即不带参数的构造函数)添加到通过API传递的对象中。在我的情况下,我必须为修补程序控制器使用带有
@RequestBody
的模型类。因此基本上就是这样
@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
import javax.ws.rs.*;
import com.sun.jersey.spi.resource.Singleton;
@Singleton
@Path("root")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class SampleRestService { ..
@PUT
@Path("sample")
public void update(Sample whitelist) throws SampleException {
// do some
}
class Sample{
int x,y;
public sample(int x, int y){
// boring stuff
}
}