【问题标题】:How to support JSONP with Spring MVC and multiple response types如何使用 Spring MVC 和多种响应类型支持 JSONP
【发布时间】:2025-12-30 13:00:10
【问题描述】:

我在控制器中有一个方法,它将根据请求返回 HTML 或 JSON。这是这种方法的一个精简示例,以我在this question 中找到的有关如何执行此操作的信息为模型:

@RequestMapping(value="callback")
public ModelAndView callback(@RequestParam("c") String c) {
    Map response = new HashMap<String, String>();
    response.put("foo", "bar");
    return new ModelAndView("fake", "data", new JSONPObject(c, response));
}

我将 JSONPObject 放入模型中,因为如果请求 HTML,我必须能够从呈现的视图中访问它。但是当我使用回调渲染 JSON 时,这会带来一个问题:

curl 'http://localhost:8080/notes/callback.json?c=call'
{"data"call(:{"foo":"bar"})}

如您所见,因为我将数据放在模型的“数据”槽中,所以当模型呈现为 JSON 时,会有额外的包装。我正在寻找的是呈现的 JSON(技术上是 JSONP)看起来像这样:

call({"data":{"foo":"bar"}})

任何人都可以在不破坏返回在渲染期间访问 JSONPObject 的视图的能力的情况下找到我想要去的地方吗?

【问题讨论】:

    标签: json spring spring-mvc jsonp jackson


    【解决方案1】:

    这就是我在 Spring MVC 中使用 JSONP 的方式,只需根据您的需要进行修改即可:

    在服务器端:

    @RequestMapping(value="/notes/callback.json", method=RequestMethod.GET)
    public void jsonpCallback(@RequestParam("callback") String callback, HttpServletResponse response) {
       response.setContentType("text/javascript; charset=UTF-8");
       PrintWriter out = response.getWriter();
       out.print(callback + "(" + jsonDataString + ")");
    }
    

    在客户端:

    <script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
    <script type="text/javascript">
    
    function yourfunction() {
        jQuery.getJSON("http://localhost:8080/notes/callback.json?callback=?", 
            function(data) {
                alert(data.someParam);
            });
    }
    
    </script>
    

    【讨论】:

      【解决方案2】:

      我想通了。渲染 JSON 时,Spring 根据我的配置使用 MappingJacksonJsonView。该视图有一个属性告诉它在地图中查找单个项目并在渲染之前将其提取出来。设置该属性后,现在可以使用了。

          <property name="defaultViews">
              <list>
                  <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" >
                      <property name="extractValueFromSingleKeyModel" value="true" />
                  </bean>
              </list>
          </property>
      

      【讨论】:

      • 我很困惑。 extractValueFromSingleKeyModel 与 jsonp 没有任何关系,如果我理解正确,它需要在响应正文中调用函数。此函数名称通常通过查询字符串传递给服务器(例如 callback=foo)。
      最近更新 更多