【问题标题】:How do I could add additional header on Response Body如何在响应正文上添加额外的标头
【发布时间】:2013-11-27 00:32:06
【问题描述】:

只看SpringMVC-3.2.x控制器动作方法的代码sn-p。生成JSON 非常容易,但无法仅为特定控制器的此操作/特定操作方法添加额外的自定义标头。并非所有JSON @ResponseBody 操作方法都通用。

@RequestMapping(value="ajaxDenied", method = RequestMethod.GET)
public @ResponseBody Map<String, Object> ajaxDenied(ModelMap model) {

    Map<String, Object> message = new HashMap<String, Object>();
    message.put("severity", "error");
    message.put("summary", "Restricted access only");
    message.put("code", 200);

    Map<String, Object> json = new HashMap<String, Object>();
    json.put("success", false);
    json.put("message", message);

    return json;
}

以不同的方式,我可以根据需要添加额外的标题,但是在生成纯 JSON 时会出现一些问题。它生成错误的JSON 并且能够解析少数浏览器。

@RequestMapping(value="ajaxSuccess", method = RequestMethod.GET)
public ResponseEntity<String> ajaxSuccess(){
    Map<String, Object> message = new HashMap<String, Object>();

    message.put("severity", "info");
    message.put("location", "/");
    message.put("summary", "Authenticated successfully.");
    message.put("code", 200);

    Map<String, Object> json = new HashMap<String, Object>();
    json.put("success", true);
    json.put("message", message);

    String data = "";
    try {
        ObjectMapper mapper = new ObjectMapper();
        data  = mapper.writeValueAsString(json);
    } catch (Exception e) { //TODO
    }
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/json; charset=UTF-8");
    headers.add("X-Fsl-Location", "/");
    headers.add("X-Fsl-Response-Code", "302");
    return (new ResponseEntity<String>(data, headers, HttpStatus.OK));
}

此操作方法可以生成带有转义字符的JSON 字符串,而不是纯JSON,因此取决于浏览器如何解析它,它会导致chrome 失败。输出看起来像

"{\"message\":{\"summary\":\"Authenticated successfully.\",\"location\":\"/\",\"severity\":\"info\",\"code\":\"200\"},\"success\":true}"

但我们想要的输出

{
  "message":{
    "summary": "Authenticated successfully.",
    "location":"/",
    "severity":"info",
    "code":"200"
  },
  "success":true
}

我想根据特定控制器的特定操作条件生成带有附加标头的纯 JSON

【问题讨论】:

  • 你为什么要转换自己?让 Spring 为您处理...只需返回 ResponseEntity&lt;Map&lt;String, Object&gt;&gt; 而不是 ResponseEntity&lt;String&gt;,移除映射器并让 spring 完成繁重的工作。
  • 是的,你是对的。我太愚蠢了,无法建立这种类型的逻辑。非常感谢您的建议。
  • 您找到解决方案了吗?依赖项升级后我遇到了同样的问题。我的 ResponseEntity 的正文和引号被 \. 转义了
  • 只要按照答案我希望你会得到类似的解决方案

标签: json spring spring-mvc


【解决方案1】:

您可以将标头添加到 ResponseEntity 构建器。我觉得这样更干净。

import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;

// ...

@GetMapping("/my/endpoint")
public ResponseEntity myEndpointMethod() {

    HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8");

    return ResponseEntity.ok()
            .headers(headers)
            .body(data);
}

【讨论】:

  • HttpHeaders headers = new HttpHeaders(); headers.add("AuthorizationToken", token); return new ResponseEntity("Authentication Successl", headers, HttpStatus.OK);
  • 新版本的Spring返回ReadOnlyHttpHeaders,使用这个例子会抛出UnsupportedOperationException。
【解决方案2】:

这是 M 建议的解决方案。 Deinum

@RequestMapping(value="ajaxSuccess", method = RequestMethod.GET)
public ResponseEntity<Map<String, Object>> ajaxSuccess(){
    Map<String, Object> message = new HashMap<String, Object>();

    message.put("severity", "info");
    message.put("location", "/");
    message.put("summary", "Authenticated successfully.");
    message.put("code", 200);

    Map<String, Object> json = new HashMap<String, Object>();
    json.put("success", true);
    json.put("message", message);

    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/json; charset=UTF-8");
    headers.add("X-Fsl-Location", "/");
    headers.add("X-Fsl-Response-Code", "302");
    return (new ResponseEntity<Map<String, Object>>(json, headers, HttpStatus.OK));
}

【讨论】:

    【解决方案3】:

    您还可以使用HttpServletResponse 以更简单的方式添加您的状态和标题:

    @RequestMapping(value="ajaxSuccess", method = RequestMethod.GET)
    @ResponseBody
    public String ajaxSuccess(HttpServletResponse response) {
      response.addHeader("header-name", "value");
      response.setStatus(200);
      return "Body";
    }
    

    因此您需要添加以下 maven 依赖项提供

    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-servlet-api</artifactId>
        <version>7.0.53</version>
        <scope>provided</scope>
    </dependency>
    

    【讨论】:

      猜你喜欢
      • 2019-03-13
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-27
      • 1970-01-01
      相关资源
      最近更新 更多