coding_idiot
coding_idiot

Reputation: 13734

How to get the request body in Struts2 when using struts2-json-plugin

I am using Struts2 and request.getInputStream() can't be used, since it gives error on 2nd use, first might have already being used by any of the interceptors.

So, I believe there must be some way to get the request-body. But I didn't found anything on internet, please help.

Upvotes: 2

Views: 3126

Answers (1)

exoddus
exoddus

Reputation: 2340

As you say, the interceptor (I guess JSONInterceptor) has already done the job before for you. Probably you have a similar struts.xml structure:

struts.xml

<constant name="struts.action.extension" value="xhtml,,xml,json,action"/> 
<constant name="struts.mapper.class" value="org.apache.struts2.dispatcher.mapper.PrefixBasedActionMapper" />
<constant name="struts.mapper.prefixMapping" value="/rest:rest,: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="rest"/>  
<constant name="struts.rest.namespace" value="/rest" />

<constant name="struts.rest.negotiation.handlerOverride.application/json" value="json" />


<package name="rest" namespace="/rest" extends="rest-default">          
        <interceptors>
            <interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
        </interceptors>         

        <action name="yourAction" class="com.struts.rest.MyController">                     
            <interceptor-ref name="json" />     
            <interceptor-ref name="defaultStack"/>
        </action>
</package>

Then, If you are trying to parse a JSON request like this:

{ "token":"mh5h6jrjkvnrk56" }

You should have a Controller (or Action) like this:

package com.struts.rest;
import ...

public class MyController implements ModelDriven<Result>{

    private static final long serialVersionUID = 1L;
    private static final Logger logger = Logger.getLogger(MyController.class.getName());
    private String token;           

    // Handles GET requests 
    public String index() {                         
        logger.info("token: " + token);         
        return "index";            
    }

    // Handles /POST requests
    public String create(){    
        // ....
        return "create"     
    }

    // Handles /PUT requests
    public HttpHeaders update() {   
        // ....
        return "update"
    }           

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }
}

In a RequestAware/ServletRequestAware Action you should access the request with request.getInputStream(), but when the JSONInterceptor acts, just let him do the work. Create as many fields as JSON elements want to be parsed in the Action/Controller. In this example I'm creating a String token field (with it's setter and getter) to hold the content of the JSON element "token".

When a /GET (with {"token":"mh5h6jrjkvnrk56"}) is done, index() is called and the field token has the value "mh5h6jrjkvnrk56" (as in the example).

Upvotes: 1

Related Questions