「求助」Spring 同一个接口根据 Content-Type 返回不同的数据

2016-10-25 17:11:05 +08:00
 int64ago

需求是具体是这样的,目前的后端是 Spring 渲染好 Freemarker 页面后直接返回 HTML 页面

代码可能如下:

 @RequestMapping("/index")
 public String hello(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
     model.addAttribute("name", name);
     return "index";
 }

我的理解就是, Model 先填充数据,然后再用 Model 填充 index.ftl ,然后再返回 index.html

但是,我有时候的需求是,如果我请求的 Content-Type 指定是 json 的话,那么直接把 Model 里的数据当作 JSON 返回即可,不要去渲染 ftl 了

我看到网上大多数的解决方法是这样的:

@Controller
public class PersonController 
{

 private static List<Person> personList;

 static
 {
  personList = 
    Arrays.asList(new Person[] 
      { new Person(1, "Pas", "Apicella"),
           new Person(2, "Lucia", "Apicella"),
           new Person(3, "Lucas", "Apicella"),
           new Person(4, "Siena", "Apicella")
         });   
 }

    @RequestMapping(value="/people", 
              method = RequestMethod.GET, 
              produces={"application/xml", "application/json"})
    @ResponseStatus(HttpStatus.OK)
    public @ResponseBody People listWithJSON() 
    {
     return new People(personList);

    }
    
    // View-based method
    @RequestMapping(value = "/people", method = RequestMethod.GET)
    public String listWithView(Model model, HttpServletResponse response, HttpServletRequest request) 
    {
         
     // Call RESTful method to avoid repeating code
     model.addAttribute("peopleList", listWithJSON().getPeople());

     // Return the view to use for rendering the response
     return "people";
    }
} 

还有这样

其实,都是一类解决方法

这样做的问题很明显:

从编程角度看,我觉得是否有种方法,在稍微底层逻辑上加个类似 Monkey Patch 或者 AOP 类似方法,可能就几行代码,也可能仅仅是配置,就可以实现这个需求呢?

如果这个从技术上来看不可行,是否有代价非常小的做法呢?

PS :我本人不是 Java 程序员,表述有不合规的地方请指出

2964 次点击
所在节点    程序员
6 条回复
int64ago
2016-10-25 17:12:49 +08:00
@murmur
@FrankFang128

看到两位经常讨论 Java ,跪求解答
zhuangzhuang1988
2016-10-25 17:25:05 +08:00
调试下 就好了.. 记得,好像,在 resolver 上....
KingOfUSA
2016-10-25 17:29:56 +08:00
不是程序员的话,把这样的事情交给程序员就好啦。要相信你的程序员
PEP4JASON
2016-10-25 18:51:53 +08:00
如果是 JSON 的话直接打印出来就行了 不需要传值到页面上 再做相关处理 ,不知道我是不是理解对了
safilar
2016-10-25 19:16:15 +08:00
关注中
johnj
2016-10-26 09:38:00 +08:00
Spring MVC 内置 Content Negotiation 机制
如果你的请求里面带有后缀的话 举个例子 index.json 就会认为请求的数据是 json 。后缀优先级高
Accept header 优先级较低。
所以前端我建议请求不带后缀 统一用 header 然后不带 header 的给设一个默认的 比如 freemarker
思路是这样。搜一下 spring mvc content negotiation 吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/315374

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX