Java 春季MVC、百里香;休息

Java 春季MVC、百里香;休息,java,android,rest,spring-mvc,thymeleaf,Java,Android,Rest,Spring Mvc,Thymeleaf,我目前有一个项目,使用Spring控制器和Thymeleaf创建一个小型浏览器应用程序。控制器类声明为 @Controller public class MyController { 在控制器内部,我有一个GET定义为 @RequestMapping(value = "/foobars", method = RequestMethod.GET) String index(Model model, --- more params ---) { //call repository and

我目前有一个项目,使用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"
}
调用存储库和get-foobarList是对MongoRepository的调用,定义为:

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

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

    ... additional @RestResources cut for brevity ...
}
公共接口foobarepository扩展了MongoRepository<。。。为简洁而裁剪>{
@RestResource(rel=“按id”)
标记findMarkerById(字符串id);
…额外的@RestResources为简洁而剪裁。。。
}
同样,浏览器应用程序看起来很棒。GET调用存储库,用foobars列表填充模型,Thymeleaf使用该列表来完成它

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

问题:是否有办法以某种方式使用相同的@Controller,或者我是否必须使用@RestController和/restfoobar端点来维护第二个FoobarRestController?第二个REST控制器确实可以工作,但看起来有点马虎。。。糟糕的设计

你的想法和建议

再次感谢。
-Rich

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

@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
    }
}
@RequestMapping(“/foobars”)
抽象类控制器{
@请求映射
抽象listAll()
}
@控制器
类FoobarHtmlController扩展了FoobarBaseController{
@重写ModelAndView listAll(){
新模型和视图('foobars/foobarThymeleafTemplate',[foobars:foobarsslist])
}
}
@RestController
@RequestMapping('/foobars',products=MediaType.APPLICATION\u JSON\u VALUE)
类FoobarJsonController扩展了FoobarBaseController{
@覆盖集合listAll(){
餐饮业者
}
}
或者,如果检查输入等有大量工作要做,您可以在
BaseController
中实现,并有一个
抽象列表所有响应(DomainObject foo)
,然后返回相应的
ModelAndView
(HTML)或DTO(JSON)


这种方法的一个缺陷是不能只覆盖部分
@RequestMapping
,因此在指定
products
参数时必须重复类的部分映射,但可以毫无问题地继承方法级映射。

Expose Crud

使用
@Controller
处理HTML页面并使用存储库,您可以通过rest API为crud等基本操作公开实体,方法是使用
SPRING-DATA-rest
公开实体。我认为您已经通过查看代码来完成了

 @RestResource(rel = "by-id") 
    Marker findMarkerById(String id);
公开业务逻辑

如果要公开任何业务逻辑,必须创建
服务
层,并通过
@Controller
为网页调用它。并为web API接口创建另一个控制器作为
@RestController

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

由于您不需要web页面中的所有逻辑来暴露于API,如果您可以将代码命名为
app.web
app.API
,那么使用单独的控制器进行REST可能是一种干净的代码设计实现

思想食粮


为网页和android使用完整的RESTAPI实现。然后使用
angularjs
backboneJs
使用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
        }
}

尽管您在两年前回答了这个问题,我同意在后端使用一个完整的rest api,然后在前端使用一个javascript框架,这在逻辑上应该是社区应该努力争取的,但是仍然几乎没有关于stackoverflow的问题,也几乎没有关于如何做到这一点的文档或教程,或者Java社区非常抵制更改,或者从长远来看,这不太管用,您认为呢?上面的api
/hello.html
如何返回thymeleaf html?这是通过thyme leaf传递的返回语句/hello.html是它响应的URL。