【发布时间】:2019-04-22 14:34:01
【问题描述】:
我正在尝试实现一种允许用户(包括匿名用户)阅读有关某些项目的评论的方法。我想使用两个路径变量,所以我不会重复自己的代码。这就是 Controller 方法的样子:
@RestController("/reviews")
@AllArgsConstructor
public class ReviewController {
@Autowired
private ReviewService reviewService;
@GetMapping("/{type}/{id}")
public ReviewDTO readReview(@PathVariable String type, @PathVariable long id) {
return reviewService.readReview(type, id);
}
每种类型都有自己的实体,所以我想使用类型变量来确定,应该使用哪个存储库。下面是 ReviewService.readReview 方法的实现:
public ReviewDTO readReview(String type, long id) {
switch (type) {
case "rides":
return new RideReviewDTO(findRideReview(id));
case "beacons":
return new TransceiverReviewDTO(findTransceiverReview(id));
case "backpacks":
return null;
default:
return null;
}
}
当我运行测试时,请求看起来完全符合其应有的样子:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /reviews/rides/1
Parameters = {}
Headers = {}
Body = null
但我遇到了一个错误。这是我在 Postman 中尝试执行此请求时得到的响应:
{
"timestamp": "2018-11-20T07:08:39.145+0000",
"status": 405,
"error": "Method Not Allowed",
"message": "Request method 'GET' not supported",
"path": "/api/reviews/rides/1"
}
这是我从测试 MockMvc 中得到的完整回复:
MockHttpServletResponse:
Status = 405
Error message = Request method 'GET' not supported
Headers = {Allow=[POST], X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY]}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
我不确定出了什么问题,在尝试调试时,甚至没有达到控制器中的方法。这就是我配置安全配置的方式:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PowderizeUserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and()
.headers().and()
.authorizeRequests()
.antMatchers("/users", "/users/confirm/**", "/users/forgotPassword").anonymous()
.antMatchers(HttpMethod.GET, "/reviews/*").permitAll()
.anyRequest().authenticated().and()
.httpBasic().and()
.logout().permitAll().and()
.csrf().disable();
}
编辑
@Alien 给出的答案是正确的一个,但还有一个问题——在安全配置方法中,.antMatchers(HttpMethod.GET, "/reviews/*").permitAll() 的模式也很糟糕。应该有/reviews/**,否则请求将不包括以下目录。
【问题讨论】:
标签: rest http spring-boot servlets