java 如何在Struts2中返回HTTP错误状态码*和*内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5904821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:21:58  来源:igfitidea点击:

How to return HTTP error status code *and* content in Struts2

javastruts2

提问by NobodyMan

I have a Controller that receives accepts http file uploads and responds with a JSON confirmation. If there is is any sort of problem with the procsessing of the upload I want to return an HTTP error status code (e.g. 403 for malformed requests or 500 for a general processing error), but I also want to send a JSON list of detailed error messages. I know how to return a 500 error (thanks to this post) but I don't know how to return the 500 code and still send content.

我有一个控制器,它接收接受 http 文件上传并以 JSON 确认响应。如果上传处理有任何问题,我想返回一个 HTTP 错误状态代码(例如 403 表示格式错误的请求或 500 表示一般处理错误),但我也想发送详细错误的 JSON 列表消息。我知道如何返回 500 错误(感谢这篇文章),但我不知道如何返回 500 代码并仍然发送内容。

Here's a snippit of my code (which doesn't do what I want it to):

这是我的代码的一个片段(它没有做我想要的):

@Action(value = "upload", results = { 
  @Result(name = SUCCESS, type = "freemarker", location = "results.ftl", params = { "contentType", "text/plain" }), 
  @Result(name = ERROR, type = "freemarker", location = "error.ftl", params = { "contentType", "text/plain" }), 
  @Result(name = ERROR, type = "httpheader", params = { "status", "500" }) 
})

public String upload() {
  //do stuff
  if(CollectionUtils.isEmpty(getActionErrors()) {
    return SUCCESS;
  } else {
     return ERROR;
  }
}

采纳答案by Ty Danielson

This is an old post, but if you are using the Struts-JSON which I suggest using you can simply return an error object with what you want and attach the status code like below:

这是一篇旧帖子,但如果您使用的是我建议使用的 Struts-JSON,您可以简单地返回一个带有您想要的错误对象并附加如下状态代码:

@Result(name = ERROR, type="json", 
        params = {"root","errorResponse", "statusCode", "500"}
)   

回答by NobodyMan

Update 2/24/15: ty-danielson's answeris the correct one. It applies to JSON responses, which is what I wanted even though I was using freemarker templates to generate them (another bad idea).

2015 年 2 月 24 日更新ty-danielson 的答案是正确的。它适用于 JSON 响应,这是我想要的,即使我使用 freemarker 模板来生成它们(另一个坏主意)。

If you really want a freemarker template with error status code:My original answer is stillthe wrong approach because it's bad form to access the ServletResponse from inside an action method. Struts' built-in FreemarkerResult does not accept a status code parameter, but you can easily add this functionality by subclassing it (example taken from GBIF project)

如果你真的想要一个带有错误状态代码的 freemarker 模板:我原来的答案仍然是错误的方法,因为从操作方法内部访问 ServletResponse 是一种错误的形式。Struts 的内置 FreemarkerResult 不接受状态代码参数,但您可以通过对其进行子类化来轻松添加此功能(示例来自GBIF 项目

/** 
 * Same as FreemarkerResult, but with added 'statusCode' parameter.  
 * (don't forget to register this result type in struts-config.xml)
 */
public class FreemarkerHttpResult extends FreemarkerResult {
  private int status;

  public int getStatusCode() {
    return status;
  }

  public void setStatusCode(int status) {
    this.status = status;
  }

  @Override
  protected void postTemplateProcess(Template template, TemplateModel data) throws IOException {
    super.postTemplateProcess(template, data);
    if (status >= 100 && status < 600) {
      HttpServletResponse response = ServletActionContext.getResponse();
      response.setStatus(status);
    }
  }
}

Then declare your action mapping like so:

然后像这样声明你的动作映射:

@Action(value = "myAction", results = { 
    @Result(name = SUCCESS, type = "freemarker", location = "results.ftl"), 
    @Result(name = ERROR, type = "freemarkerhttp", location = "error.ftl", params = { "statusCode", "500"})            
})
public String myAction() {
   //do stuff, then return SUCCESS or ERROR
}

My Original Answer

我的原答案

So, I'm not sure if this is "proper" from a struts2 perspective, but here's a solution that acomplishes my goal of returning the http error code while still being able to render a freemarker template. I'll mark this as the answer until a better one comes along.

所以,我不确定从 struts2 的角度来看这是否“正确”,但这里有一个解决方案,它实现了我返回 http 错误代码的目标,同时仍然能够呈现 freemarker 模板。我会将此标记为答案,直到出现更好的答案。

@Action(value = "upload", results = { 
@Result(name = SUCCESS, type = "freemarker", location = "results.ftl", params = { "contentType", "text/plain"}), 
@Result(name = ERROR, type = "freemarker", location = "error.ftl", params = { "contentType", "text/plain"})            
})
    public String upload() {
       try {
       //do stuff
       } Catch(SomeExceptionType ex) {
            addActionError("you did something bad");
            HttpServletResponse response = ServletActionContext.getResponse();
            response.setStatus(400);
       }


    }

回答by Vlad C?lin Buzea

In case someone is looking for the struts.xmlversion of the accepted answer, I'm going to leave it here:

如果有人正在寻找已接受答案的struts.xml版本,我将把它留在这里:

    <action name="upload"
        class="...">
        <exception-mapping exception="java.lang.Exception" result="error"/>
        <result name="error" type="json">
            <param name="statusCode">418</param>
        </result>
        <result name="Success" type="json" />
    </action>

回答by Jeremy

I don't have time to setup a test Struts2 application, but maybe have a single error result:

我没有时间设置测试 Struts2 应用程序,但可能只有一个错误结果:

@Result(name = ERROR, type = "freemarker", location = "error.ftl",
    params = { "contentType", "text/plain", "status", "500" })