在Struts2 RESTful插件的POST请求中返回响应

4

我已经从这里获取信息并实现了Struts2 REST API。

Struts2 Rest Plugin

在Struts2的RESTful插件中,有没有办法返回自定义响应?我已经完成了所有必要的更改,例如:

struts.rest.content.restrictToGET = false

我从这个问题中获取了信息。但是我仍然遇到了这个错误。

No result defined for action `com.web.Controller.RestDemoController` and result create, 

如果我不添加上述行,我仍然会得到相同的响应。
这是我在struts.xml中提供的操作:
<action name="restdemo" class="com.web.Controller.RestDemoController">
    <interceptor-ref name="customRestStack"></interceptor-ref>
</action>

这个程序可以处理所有的请求,包括GETPOSTPUTUPDATE
将post方法的返回类型从HttpHeader更改为String后,我仍然遇到相同的错误。
Error 404: No result defined for action com.web.Controller.RestDemoController and result <?xml version="1.0" encoding="UTF-8"?> <Status><code>200</code><message>Success</message></Status>

这是我为POST编写的代码:

public HttpHeaders create(){
    System.out.println(envision2Data.toString());
    return new DefaultHttpHeaders("create").withStatus(200);
}

这是使用POST请求方法并返回类型为String的内容:

public String create(){
    System.out.println(envision2Data.toString());
    return "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <Status><code>200</code><message>Success</message></Status>";
}

我发送请求时,无论是xml还是json,都能得到完美的响应。根据扩展名,我会得到xml或json,如http://localhost:8080/restdemoapplication/restdemo.xmlhttp://localhost:8080/restdemoapplication/restdemo.json
对于POST请求,我像这样发送请求: enter image description here 你可以看到我得到的响应。我为post编写的方法在上面被命名为create。我有数据在body中,并且在create方法中完美地获取了数据。
现在在post中,我已经看到了多个示例,例如: struts-rest, stuts2-rest-sample, struts2-rest-shopping-list
我不希望像这些应用程序那样返回POST请求的响应。我想返回自己的响应,它将是一个状态码和一条消息,就像这样。
<?xml version="1.0" encoding="UTF-8"?> <Status><code>200</code><message>Success</message></Status>

在调试后,我发现 struts2-rest-plugin 中的 DefaultContentTypeHandlerManager 将 xhtml 视为默认模板。但实际上应该是 XML 或 JSON。
我想返回
 code : 1xx,2xx,4xx
 message: Success, Fail

当处理POST请求时,可以使用XML或JSON格式。该应用程序支持非RESTful请求和RESTful请求。我可以将XML或JSON设置为默认模板,但不想这样做,因为它会影响非RESTful请求。

我已经提供了通过POST请求调用的代码,并且我还提供了在代码上方的POST请求后的结果。 - Muhammad Danish Khan
@AleksandrM,我们在Struts2中的REST API是否真的需要结果?它不应该返回成功或失败响应吗? - Muhammad Danish Khan
你的意思是什么?你也可以返回字符串。 - Aleksandr M
@MuhammadDanishKhan 这是我在看到这个问题后看到的内容:“有没有办法加载我的自定义ContentTypeHandlerManager或返回自定义响应”。我的问题是它与您“具体说,我想要一个自定义响应发送到客户端”的说法有什么关系。 - Roman C
@AleksandrM 我已更新了问题,请仔细阅读。 - Muhammad Danish Khan
显示剩余10条评论
2个回答

2
你误解了与struts2-rest-plugin一起使用的内容类型的概念。

Content Types

In addition to providing mapping of RESTful URL's to Controller ( Action ) invocations, the REST plugin also provides the ability to produce multiple representations of the resource data. By default, the plugin can return the resource in the following content types:

  • HTML
  • XML
  • JSON

There is nothing configure here, just add the content type extension to your RESTful URL. The framework will take care of the rest. So, for instance, assuming a Controller called Movies and a movie with the id of superman, the following URL's will all hit the

http://my.company.com/myapp/movies/superman
http://my.company.com/myapp/movies/superman.xml
http://my.company.com/myapp/movies/superman.xhtml
http://my.company.com/myapp/movies/superman.json

Note, these content types are supported as incoming data types as well. And, if you need, you can extend the functionality by writing your own implementations of org.apache.struts2.rest.handler.ContentTypeHandler and registering them with the system.

该插件通过内容类型来服务请求,可以通过提供操作扩展或提供数据类型来定义。传入的数据类型由"Content-Type"头部定义,传出的数据类型由"Accept"头部定义。

要使POST请求返回数据,您需要在Struts配置文件struts.xml中添加一个常量:

<constant name="struts.rest.content.restrictToGET" value="false"/>

Struts发行版中提供了名为struts2-rest-showcase的演示应用程序。在添加常量之后,您可以使用某些HTTP客户端测试应用程序。

POST http://localhost:8080/orders
Accept: application/json
Content-Type: application/json
{
  "id":"23423423",
  "clientName":"Roman C",
  "amount": 1000
}
 -- response --
201 
Content-Language:  en-US
Content-Length:  54
Content-Type:  application/json;charset=UTF-8
Date:  Sat, 07 Oct 2017 20:44:39 GMT
ETag:  -735433458
Location:  http://localhost:8080/orders/23423423

{"amount":1000,"clientName":"Roman C","id":"23423423"}

好的,我明白了,但是你在位置中给出了URI。我不想这样做。我只想返回一条简单的消息。 - Muhammad Danish Khan
请给我一个例子。 - Muhammad Danish Khan
我已经添加了一个名为response的属性,类型为String。但是我仍然得到相同的错误。 - Muhammad Danish Khan
该操作返回一个字符串,它表示结果代码。您可以检查是否经由rest action调用进行处理并返回结果。如果是重定向结果或redirectAction结果,则不是错误而是响应,其在执行代码配置的操作后返回给客户端。 - Roman C
添加 <constant name="struts.rest.content.restrictToGET" value="false"/> 使得当请求类型为 POST、PUT、DELETE 时,响应变为 JSON 类型。 - Kavin Raju S
显示剩余7条评论

0

所以这就是我需要的解决方案。我所做的是

@Override
public Object getModel() {
        <!-- Changed name of the object overhere to mainObject-->
    if (mainObject == null) {
        if (responseObject != null) {
            return responseObject;
        } else if (mainObject != null) {
            return mainObject;
        }
        mainObject = new mainObject();
    }
    return mainObject;
}

然后在内容类型处理程序中。 内容类型处理程序是自定义的,因为我使用了Jackson进行JSON到对象和对象到JSON的转换。

if (paramObject instanceof MainObject) {
        MainObject mainObject = (MainObject) paramObject;
        writer.write(mapper.writeValueAsString(mainObject));
} else if (paramObject instanceof ResponseObject) {
        ResponseObject responeObject = (ResponseObject) paramObject;
        writer.write(mapper.writeValueAsString(responeObject));
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接