繁体   English   中英

Spring MVC、Thymeleaf 和 REST

[英]Spring MVC, Thymeleaf & REST

我目前有一个使用 Spring 控制器和 Thymeleaf 的项目来创建一个小浏览器应用程序。 控制器类声明为

@Controller public class MyController {

在控制器内部,我有一个GET定义为

@RequestMapping(value = "/foobars", method = RequestMethod.GET)
String index(Model model, --- more params ---) {
    //call repository and get foobarsList
    //model.addAttribute("foobars", foobarsList);
          ...
    return "foobars/foobarThymeleafTemplate"
}

调用库,并得到foob​​arList是定义为MongoRepository呼叫:

public interface FoobarRepository extends MongoRepository< ... cut for brevity> {

    @RestResource(rel = "by-id") 
    Marker findMarkerById(String id);

    ... additional @RestResources cut for brevity ...
}

同样,浏览器应用程序看起来很棒。 GET调用存储库,使用 foobars 列表填充模型,Thymeleaf 使用该列表执行此操作。

问题:现在我需要从Android应用程序访问相同的数据,我更喜欢使用 REST 并且只在 Android 应用程序中使用 JSON。 我想保留 Thymeleaf,但会在必要时重构浏览器应用程序。

问题:有没有办法以某种方式使用相同的 @Controller 或者我是否必须使用带有 /restFoobars 端点的 @RestController 来维护第二个 FoobarRestController? 第二个 REST 控制器肯定可以工作,但它似乎有点草率……糟糕的设计。

您的想法和建议?

再次感谢。 -富有的

我的首选方法是使用继承:

@RequestMapping('/foobars')
abstract class FoobarBaseController {

    @RequestMapping
    abstract listAll()
}

@Controller
class FoobarHtmlController extends FoobarBaseController {
    @Override ModelAndView listAll() {
        new ModelAndView('foobars/foobarThymeleafTemplate', [foobars: foobarsList])
    }
}

@RestController
@RequestMapping('/foobars', produces = MediaType.APPLICATION_JSON_VALUE)
class FoobarJsonController extends FoobarBaseController {
    @Override Collection<Foobar> listAll() {
        foobarsList
    }
}

或者,如果有大量工作要做检查输入等,您可以在BaseController实现它,并有一个abstract listAllResponse(DomainObject foo)然后返回适当的ModelAndView (HTML) 或 DTO (JSON)。

这种方法的一个缺陷是你不能只覆盖@RequestMapping的一部分,所以当你指定produces参数时你必须重复类的映射部分,但是你可以继承方法级映射而没有问题。

暴露原油

使用@Controller来完成处理 HTML 页面的工作,并使用 Repository 您可以通过使用SPRING-DATA-REST公开您的实体,通过 rest API 公开实体以进行基本操作,例如 crud。 我想你已经通过查看代码做到了

 @RestResource(rel = "by-id") 
    Marker findMarkerById(String id);

暴露业务逻辑

如果您想公开任何业务逻辑,您必须创建一个Service层,并通过您的@Controller为网页简单地调用它。 并为 Web API 接口创建另一个控制器作为@RestController

您可能会注意到,这里没有复制任何代码,因为逻辑是在服务层的单个点编写的。 但是为了不同的目的使用不同的控制器。

由于您不需要将网页中的所有逻辑都暴露给 API,如果您可以将代码命名为app.webapp.api ,那么使用单独的 REST 控制器可能是您代码的干净设计实现。

深思熟虑

为网页和 android 使用完整的 REST API 实现。 然后使用AngualarJSbackboneJs用HTML5 做客户端实现。 我认为这就是未来。

您似乎可以将 @RestController 用于 Thymeleaf HTML 和 REST/JSON。

以下对我有用:

@RestController
@RequestMapping("/projects")
public class ProjectController {

        /**
         * A REST reponse (JSON)
         * 
         * @param name
         * @return
         */
        @GetMapping(value = "/{name}")
        public Project get(@PathVariable String name) {
            return new Project(1l, name); 
        }

        /**
         * A thymeleaf HTML response
         */
        @GetMapping(value = "/hello.html")
        public String getAsHtml() {
            return "hello"; //name of the html file in src/main/resources/templates
        }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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