• 请不要在回答技术问题时复制粘贴 AI 生成的内容
int64ago
V2EX  ›  程序员

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

  •  
  •   int64ago ·
    int64ago · Oct 25, 2016 · 3362 views
    This topic created in 3490 days ago, the information mentioned may be changed or developed.

    需求是具体是这样的,目前的后端是 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 程序员,表述有不合规的地方请指出

    6 replies    2016-10-26 09:38:00 +08:00
    int64ago
        1
    int64ago  
    OP
       Oct 25, 2016
    @murmur
    @FrankFang128

    看到两位经常讨论 Java ,跪求解答
    zhuangzhuang1988
        2
    zhuangzhuang1988  
       Oct 25, 2016
    调试下 就好了.. 记得,好像,在 resolver 上....
    KingOfUSA
        3
    KingOfUSA  
       Oct 25, 2016
    不是程序员的话,把这样的事情交给程序员就好啦。要相信你的程序员
    PEP4JASON
        4
    PEP4JASON  
       Oct 25, 2016
    如果是 JSON 的话直接打印出来就行了 不需要传值到页面上 再做相关处理 ,不知道我是不是理解对了
    safilar
        5
    safilar  
       Oct 25, 2016
    关注中
    johnj
        6
    johnj  
       Oct 26, 2016
    Spring MVC 内置 Content Negotiation 机制
    如果你的请求里面带有后缀的话 举个例子 index.json 就会认为请求的数据是 json 。后缀优先级高
    Accept header 优先级较低。
    所以前端我建议请求不带后缀 统一用 header 然后不带 header 的给设一个默认的 比如 freemarker
    思路是这样。搜一下 spring mvc content negotiation 吧
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2985 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 09:32 · PVG 17:32 · LAX 02:32 · JFK 05:32
    ♥ Do have faith in what you're doing.