Andrew
Andrew

Reputation: 41

Struts2-Rest: Manual HTTP 5xx doesn't return content

I'm attempting to manually return a HTTP 4xx or 5xx with a custom error message. It works perfectly for GET but returns empty content for PUT and POST. Thank you in advance to anyone who can suggest how to get the PUT and POST working!

These are the calls I'm making to the webservice:
GET /webapp/orders/A.json - returns HTTP 500 and the error message as content
PUT /webapp/orders/A.json - returns HTTP 500 and content-length=0

getModel() is called in both instances, the message just doesn't make it back to Chrome for PUT.

Here's sample code that produces the error:

OrdersController

package com.test.controller;

import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.apache.struts2.convention.annotation.Namespace;
import com.opensymphony.xwork2.ModelDriven;

@Namespace("/rest")
public class OrdersController implements ModelDriven<Object> {

    // GET /orders/A
    public HttpHeaders show() {
        return new DefaultHttpHeaders().withStatus(500);
    }

    // PUT /orders/A
    public HttpHeaders update() {
        return new DefaultHttpHeaders().withStatus(500);
    }

    public void setId(String id) {
        // Nothing
    }

    public Object getModel() {
        return new String("{ \"message\": \"An error occurred.\"}");
    }

} 

Struts

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <constant name="struts.convention.action.suffix" value="Controller"/>
    <constant name="struts.convention.action.mapAllMatches" value="true"/>
    <constant name="struts.convention.default.parent.package" value="rest-default"/>
    <constant name="struts.convention.package.locators" value="controller"/>    
</struts>

Web

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="starter" version="2.4"
     xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Orders</display-name>

    <filter>
        <filter-name>action2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>action2</filter-name>
        <url-pattern>/rest/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

AngularJS Test Harness

var orderApp = angular.module('orderApp', []);

orderApp.run(function($http) {
    $http.get("rest/orders/A.json");
    $http.put("rest/orders/A.json", {"orderId":"A"} );
});

Environment: Struts2 (2.3.16.3), Rest-Plugin, Convention, Java7, Tomcat7, Maven

Upvotes: 3

Views: 689

Answers (1)

Andrew
Andrew

Reputation: 41

Adding <constant name="struts.rest.content.restrictToGET" value="false"/> to struts.xml solved the problem. Kudos to @ontk for this answer to another question. Thanks to everyone who tried to help me out.

Upvotes: 1

Related Questions