我有一个Java REST API,供2个不同的使用者使用。默认情况下,REST原则我的API应该定义请求标头的名称。但是现在我没有共同的情况。消费者使用不同的安全层,该安全层提供不同的头,这两种方式都意味着相同的参数。
示例方法: (非真实代码)对于第一个消费者:
@PostMapping("/number")
Integer getNumber(@RequestHeader("no") String number, @RequestBody User user) {
/*...*/
}
第二消费者:
@PostMapping("/number")
Integer getNumber(@RequestHeader("number") String number, @RequestBody User user) {
/*...*/
}
我在一个控制器中最多有10个方法,它们应该具有相同的名称和逻辑,但标头不同。请求路径前缀可以不同。
如何简化REST控制器并且不使用相同的方法和相同的逻辑创建两个不同的控制器?
我尝试了几个示例,使用相同的方法,但映射不同,创建了一个具有2个不同接口的控制器。
Controller class
@RestController
@RequestMapping(path ="/application")
@Api(tags = {"application"})
public class ApplicationController implements AppMapping1, AppMapping2 {
@Override
public Integer getNumber(String number, User user) {
/*...*/
}
}
第一个界面
interface AppMapping1 {
@PostMapping("/num")
Integer getNumber(@RequestHeader("num") String number, @RequestBody User user);
}
第二界面
interface AppMapping2 {
@PostMapping("/number")
Integer getNumber(@RequestHeader("number") String number, @RequestBody User user);
}
控制器仅与第一个接口映射。因此,
http://.../application/num
可以正常工作,但是http://.../application/number
-获取404
错误代码。这意味着Java Spring-Boot没有这种功能。需要更多的想法。
[Java 8
开发的项目; spring-boot:2.1.1.RELEASE
; gradle
您可以删除@RequestHeader
批注并考虑执行以下操作:
@PostMapping("/number")
Integer getNumber(HttpServletRequest request, @RequestBody User user) {
String number = request.getHeader("num");
if(number == null){
number = request.getHeader("number");
}
/*...*/
}
如果您希望使用更清洁的方法,请考虑创建一个使用HttpServletRequest
对象并返回所需标头值的util类。
重复两次或多次重复同一代码块只是为了接收具有不同名称(number
和no
)的相同输入,这对维护不友好。相反,建议阅读所有标头并遍历所有标头以使用不同的名称获取输入。
样本代码
@PostMapping("/number")
public Integer getNumber(@RequestHeader Map<String, String> headers) {
String number = headers.containsKey("number") ? headers.get("number") : headers.get("no");
if(Objects.isNull(number)) {
throw new RuntimeException("Number input not received from header!");
}
// relevant processing
}
这是因为您具有相同的签名,并且java将它们标记为相同的方法,所以其中一个在类中使用。您可以简化重命名该方法名称之一的工作。
第一个界面
interface AppMapping1 {
@PostMapping("/num")
Integer getNum(@RequestHeader("num") String number, @RequestBody User user);
}
第二界面
interface AppMapping2 {
@PostMapping("/number")
Integer getNumber(@RequestHeader("number") String number, @RequestBody User user);
}
绝对需要在控制器类中重写getNum()
。