[英]Spring Boot. Forward on RestController
我正在实施一种替换短链接的机制。
我需要将请求转发给另一个控制器。 我在模型上找到了如何在 spring 中执行此操作的示例,但我不明白如何在 RestControllers 中执行此操作
例如我发现的(使用模型)
@Controller
public class ShrotLinkForwardController {
@RequestMapping("/s/*")
public String myMethod(HttpServletRequest request) {
return "forward:/difmethod";
}
}
或者也许我看错了方向,我需要做一个过滤器?
更新。 不知道最终的终点,是在forwarded方法中计算出来的。 所以,我不能自动连接其他控制器
有两种方法可以实现你想要的。
控制器只是普通的 Spring bean。 您可以通过自动装配获得它。
@Controller
public class ShrotLinkForwardController {
@Autowired
OtherController otherController;
@RequestMapping("/s/*")
public String myMethod(Model model) {
otherController.doStuff();
return ...;
}
}
要触发转发,请尝试返回一个String
而不是ModelAndView
。
这是您在问题中提到的方法。 请注意,语法应为forward:/forwardURL
。 forward:
后面的字符串是指向另一个控制器的 URL,而不是方法名。
@Controller
public class ShrotLinkForwardController {
@RequestMapping("/s/*")
public String myMethod(Model model) {
return "forward:/forwardURL";
}
}
您可以注入目标控制器并简单地调用该方法
@Controller
public class ShortLinkForwardController {
@Autowired
private RestController target;
@RequestMapping("/s/*")
public String myMethod(HttpServletRequest request) {
return target.myMethod(request);
}
}
警告:与路径相关的请求属性仍将指向“/s/*”
或者使用 ResponseEntity 并设置目标位置...
public ResponseEntity<Void> myMethod(HttpServletRequest request) {
return ResponseEntity.status(302).location(URI.create(...)).build();
}
更新。 不知道最终的终点,是在forwarded方法中计算出来的。 所以,我不能自动连接其他控制器
但我不明白如何在 RestControllers 中做到这一点
我可以在这里看到一些可能的不良设计迹象,因此我将尝试解释可能的问题以及应如何根据最佳实践进行处理。
如果您的要求是转发给另一个控制器,那么这可能表示 3 个可能的问题:
可以将另一个控制器(您说要转发到的)要完成的工作提取到服务层的服务方法中。 然后两个控制器可以调用相同的服务方法,而每个控制器都不会知道另一个。
您的需求也可能是以下问题的指标。 出于完全相同的实际原因,您需要 2 个控制器,以便它们为相同的输入提供完全相同的输出,但可以从 2 个不同的 URL 获得。 如果是这种情况,那么您可以只使用 1 个控制器并允许它针对两个 URL 执行。 请参阅以下代码来实现此目的:
@RequestMapping({"/s/*", "/s2/*}) public String myMethod(HttpServletRequest request) { return "some response"; }
您只需要向客户端公开 1 个 URL,它将为所有内容提供服务。 那么使用 forward 的方法也不会给你带来好处,因为如果客户愿意的话,他可以直接联系到另一个转发的控制器。 在这种情况下,您可以实施 1 个控制器,然后根据需要构建不同的响应。 尽管 Sonar 和其他代码审查工具不建议通过标记返回ResponseEntity<?>
的方法,但您可以在RestController
中执行此操作。 例子:
@RequestMapping("/s/*") public ResponseEntity<?> myMethod(HttpServletRequest request) { if (condition 1) { return new ResponseEntity<YourObject1>(HttpStatus.OK); } else if (condition 2) { return new ResponseEntity<YourObject2>(HttpStatus.OK); } else { return new ResponseEntity<YourObject3>(HttpStatus.OK); } }
最后一个选择不被认为是<?>
的最佳实践,但对于这个要求,我看不到任何其他出路。
所有答案都是关于返回字符串
但我找到了另一个解决方案
如果您需要从一个 REST 端点转发到另一个 REST 端点,它可能会帮助解决我的问题的人。 它也可以应用于您的情况。
@RestController
public class CustomerController {
@GetMapping("/forwarding_endpoint")
public void makeForward(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().getServletContext().getRequestDispatcher("/forward_endpoint").forward(request, response);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.