在 Spring Boot 中从 @RestController 有条件地返回 JSON 和 (HTML) 模板

Posted

技术标签:

【中文标题】在 Spring Boot 中从 @RestController 有条件地返回 JSON 和 (HTML) 模板【英文标题】:Conditionally returning both JSON and (HTML) templates from @RestController in Spring Boot 【发布时间】:2017-03-08 16:51:37 【问题描述】:

大多数类似的问题似乎与我遇到的问题相反。

我正在使用 @RestController 构建一个基于 Spring Boot 的 web 应用程序。 JSON 响应运行良好,但现在我想支持通过模板(特别是 Thymeleaf)返回 html。所有示例都显示了这样的构建方法:

@RequestMapping(method = RequestMethod.GET)
String index()

    return "index";

只要它所在的类用 @Controller 注释就可以了。如果我用@RestController 进行注释,我会得到文字字符串“index”。这是有道理的,因为@RestController 意味着@ResponseBody

总的来说,我对此有几个问题......

在旨在返回 JSON 的方法上使用 @Controller 和显式 @ResponseBody 注释是否正确?

我担心我的 Controller 类会变得非常大,因为我将为大多数 GET 方法提供两种实现(一种用于返回 HATEOAS JSON,一种用于返回模型中包含更多内容的 HTML )。是否有建议的做法来考虑这一点?

不胜感激。谢谢!

【问题讨论】:

您仍然可以将所有代码放在一个类中(或任何有意义的类),并使用该类作为委托人来实现 2 个控制器。你所有的方法都只包含delegate.callMethod()。或者,您可以定义一个抽象基类,而不是委托,将其扩展两次。你所有的方法都只会包含 super.callParentMethod()。在这两种情况下,控制器都只是带有映射定义的空壳。 【参考方案1】:

在旨在返回 JSON 的方法上使用 @Controller 和显式 @ResponseBody 注释是否正确?

只要你的控制器很小并且只包含很少的方法。

我担心我的 Controller 类会变得非常大,因为大多数 GET 方法都会有两种实现(一种用于返回 HATEOAS JSON,一种用于返回模型中包含更多内容的 HTML)。是否有建议的做法来考虑这一点?

如果它们长大并变得难以阅读,则拆分为一个 @Controller 返回 HTML 页面和 @RestController 返回 JSON。

总而言之,关注可读性。从技术上讲,这两种方法都是正确的。

【讨论】:

【参考方案2】:
@RestController
public class SampleController     

@GetMapping(value = "/data/id", produces = MediaType.APPLICATION_JSON_VALUE)
public CustomClass get(@PathVariable String id) 
    return newsService.getById(id);


@GetMapping(value = "/data/id", produces = MediaType.TEXT_HTML_VALUE)
public String getHTML(@PathVariable String id) 
    return "HTML";

【讨论】:

【参考方案3】:

您可以返回 ViewModelAndView,而不是 String

@RequestMapping(method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
ModelAndView index()

  return new ModelAndView("index");

这允许您从带有@RestController 注释的控制器返回 HTML。

【讨论】:

以上是关于在 Spring Boot 中从 @RestController 有条件地返回 JSON 和 (HTML) 模板的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 中从 JWT 安全检查中排除 URL

如何在apache中从角度调用spring boot api

在 Spring Boot 中从 jwt 获取附加属性

Angular 2 + CORS + 带有 Spring Security 的 Spring Boot Rest Controller

在 CircleCi 中从 Spring Boot 访问 PostgreSQL 9.6

无法在 spring-boot 应用程序中从 Consul 读取配置