繁体   English   中英

弹簧靴。 在 RestController 上转发

[英]Spring Boot. Forward on RestController

我正在实施一种替换短链接的机制。

我需要将请求转发给另一个控制器。 我在模型上找到了如何在 spring 中执行此操作的示例,但我不明白如何在 RestControllers 中执行此操作

例如我发现的(使用模型)

@Controller
public class ShrotLinkForwardController {

   @RequestMapping("/s/*")
   public String myMethod(HttpServletRequest request) {
       return "forward:/difmethod";
   }
}

或者也许我看错了方向,我需要做一个过滤器?

更新。 不知道最终的终点,是在forwarded方法中计算出来的。 所以,我不能自动连接其他控制器

有两种方法可以实现你想要的。

1.直接调用目标控制器上的方法。

控制器只是普通的 Spring bean。 您可以通过自动装配获得它。

@Controller
public class ShrotLinkForwardController {

  @Autowired
  OtherController otherController;

  @RequestMapping("/s/*")
  public String myMethod(Model model) {
    otherController.doStuff();
    return ...;
  }
}

2.通过返回一个字符串触发转发

要触发转发,请尝试返回一个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 个可能的问题:

  1. 可以将另一个控制器(您说要转发到的)要完成的工作提取到服务层的服务方法中。 然后两个控制器可以调用相同的服务方法,而每个控制器都不会知道另一个。

  2. 您的需求也可能是以下问题的指标。 出于完全相同的实际原因,您需要 2 个控制器,以便它们为相同的输入提供完全相同的输出,但可以从 2 个不同的 URL 获得。 如果是这种情况,那么您可以只使用 1 个控制器并允许它针对两个 URL 执行。 请参阅以下代码来实现此目的:

     @RequestMapping({"/s/*", "/s2/*}) public String myMethod(HttpServletRequest request) { return "some response"; }
  3. 您只需要向客户端公开 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM