场景说明:在开发一个项目的时候,由于内部约定,必须在接口路径上表明版本和项目,假设版本取v1, 项目:rms,那么项目中所有接口路径的设计出来后都是:http|https://ip:port|域名/v1/rms/*;
由于路径中有/v1/rms共同的部分,所以我把它放在一个类中,该类用注解@RestController 标注表明它是一个controller 类,同时用注解@RequestMapping("/v1/rms")标注。那么所有继承该类的controller类的路径都以“/v1/rms”作为路径前缀。
1 import org.springframework.web.bind.annotation.RequestMapping; 2 import org.springframework.web.bind.annotation.RestController; 3 4 5 @RestController 6 @RequestMapping("/v1/rms") 7 public class RmsBaseController { 8 9 }
同时设计另外一个继承它的类,该类继承自RmsBaseController类,取名TestController,假设所有该类里面定义的接口都以"/test"作为前缀,自然地,会想到和之前基类一样用@RestController @RequestMapping("/test")注解该类,但是真的这样做之后,发现程序能启动,但是用 “http://ip:port/v1/rms/test/*” 访问 该类的接口后会报404错,而只能用 “http://ip:port/test/*”才能访问。
错误代码:
1 import org.springframework.web.bind.annotation.RequestMapping; 2 import org.springframework.web.bind.annotation.RequestMethod; 3 import org.springframework.web.bind.annotation.RestController; 4 import javax.servlet.http.HttpServletResponse; 5 6 @RestController 7 @RequestMapping("/test") 8 public class TestController extends RmsBaseController { 9 10 /** 11 * 添加测试接口Ping 12 * */ 13 @RequestMapping(value = "ping", method = RequestMethod.GET) 14 public final void checkApplication(HttpServletResponse response) { 15 response.setStatus(200); 16 } 17 }
请求示例:http://localhost:8090/vi/resource/test/ping
报错内容:
<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id=‘created‘>Wed Mar 07 19:38:20 CST 2018</div><div>There was an unexpected error (type=Not Found, status=404).</div><div>No message available</div></body></html>
修改方法:
将TestController类注解@RequestMapping("/test")去掉,并且在TestController的每一个接口的@RequestMapping的value值前面加上前缀“/test”。改正后的代码:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
@RestController
public class TestController extends RmsBaseController {
/**
* 添加测试接口Ping
* */
@RequestMapping(value = "/test/ping", method = RequestMethod.GET)
public final void checkApplication(HttpServletResponse response) {
response.setStatus(200);
}
}
测试示例:http://localhost:8090/v1/rms/test/ping
结果:返回状态码:200
可见 @RequestMapping("/test")不能同时注释两个有继承关系的类。
记录下踩过的坑,以便以后能绕过。