根据参数内部启动转发请求



我正在为不同类型的自定义事件调用我的API,如:

const eventTypes = [
'cards.addCard'
'cards.updateCard',
'lanes.addLane',
'lanes.updateLane'
];
fetch(`http://localhost:8080/app/${roomId}/${eventType}`, {
method: 'POST'
body: JSON.stringify(data)
...
});

eventType路径变量应该定义将调用哪一个控制器方法:

@RestController
@RequestMapping(value = "/cards")
public class CardController {
@PostMapping("/{roomId}/createCard")
public void createCard(@PathVariable Long roomId, @RequestBody MyEventData eventData) {
...
}
@PostMapping("/{roomId}/updateCard")
public void updateCard(@PathVariable Long roomId, @RequestBody MyEventData eventData) {
...
}
}
@RestController
@RequestMapping(value = "/lanes")
public class LaneController {
@PostMapping("/{roomId}/addLane")
public void addLane(@PathVariable Long roomId, @RequestBody MyEventData eventData) {
...
}
@PostMapping("/{roomId}/updateLane")
public void updateLane(@PathVariable Long roomId, @RequestBody MyEventData eventData) {
...
}
}

我更喜欢使用eventType从请求的路径变量,但我也可以把它放在请求体。

那么如何可能通过使用其参数(eventType)将相同API中的请求转发到正确的控制器方法?例如:

http://localhost:8080/app/2/cards.addCard应调用CardController.createCard()http://localhost:8080/app/2/lanes.updateLane应该调用LaneController.updateLane()

我知道这没有回答最初的问题,但通常客户端不应该规定服务器的实现细节。我会在客户端重新设计url结构,而不是试图调整服务器以满足特定客户的需求。例如

const eventTypes = [
'cards.addCard'
'cards.updateCard',
'lanes.addLane',
'lanes.updateLane'
];
const fetch = (eventType, roomId) => { // "cards.addCard", 1
// ["cards", "addCard"]
const [resource, action] = eventType.split('.');
// http://localhost:8080/app/cards/1/addCard
const url = `http://localhost:8080/app/${resource}/${roomId}/${action}`;
// perform http request ...
}

如果你仍然需要在服务器上做,那么这个逻辑可以移动到一些"通用控制器";它将处理它们并进一步转发(伪代码):

@Route("/")
class GenericController {
@RequestMapping({"/{id}/{fullAction}")
public String execute(
@PathVariable String id, 
@PathVariable String fullAction) {
final var resource = fullAction.split(".")[0];
final var action = fullAction.split(".")[1];
return "forward:/" + resource + "/" + id + "/" + action;
}
}

您可以将roomId与path属性中的eventType交换,如下所示:

@PostMapping("/createCard/{roomId}")
@PostMapping("/updateCard/{roomId}")
...

如果你想做一个重定向,你可以创建一个过滤器来做一个基于事件类型的重定向,这里是一个doFilter实现的例子:

@Override
public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String path = req.getRequestURI();

if (path.equals("/a")) {
req = new HttpServletRequestWrapper((HttpServletRequest) request) {
@Override
public String getRequestURI() {
return "/b";
}
};
}
chain.doFilter (req, res);
}

Ref: SpringBoot重定向可能存在过滤器问题

最新更新