2

I have tried multiple versions and read several related answers, but I still cant figure out why Struts is not populating my Action property user.

This is my ajax call

function save_new_user() {

    var user = 
    {       username: $('#new_user_username').val(),
            email: $('#new_user_email').val(),
            password: $('#new_user_password').val()         
    };

    user_json = JSON.stringify(user);
    console.log(user_json);

    var data = {'user': user_json};

    $.ajax({
        type : 'GET',
        url : 'SaveNewUser',
        data: data,
        dataType : "json",
        contentType: 'application/json',
        success : function(data, textStatus, jqXHR) {
            if(data) {

            }
        },
    });
}

which, by the way, print this in the console

{"username":"dd","email":"ff","password":"gg"}

My Action class (with annotations), (I am not modifying the json-default interceptor from struts2-json-plugin-2.3.24.1) is

package coproject.cpweb.actions;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ActionSupport;

import coproject.cpweb.utils.db.entities.UserDum;
import coproject.cpweb.utils.db.services.DbServicesImp;

@Action("SaveNewUser")
@ParentPackage("json-default")
@Results({
    @Result(name="success", type="json"),
    @Result(name="input", location="/views/error.jsp")
})
public class SaveNewUser extends ActionSupport{

    private static final long serialVersionUID = 1L;

    /* Services  */
    DbServicesImp dbServices;

    public DbServicesImp getDbServices() {
        return dbServices;
    }

    public void setDbServices(DbServicesImp dbServices) {
        this.dbServices = dbServices;
    }

    /* Input Json  */
    private UserDum user = new UserDum();

    public UserDum getUser() {
        return user;
    }

    public void setUser(UserDum user) {
        this.user = user;
    }

    /* Execute */
    public String execute() throws Exception  {

        // dbServices.saveUser(user);

        System.out.println(user.getUsername());

        return "SUCCESS";
    }


}

And the UserDum entity is

package coproject.cpweb.utils.db.entities;

public class UserDum {

    private String username;
    private String email;
    private String password;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

However, when the request arrives, the json interceptor of struts-json-plugin gets an exception trying to set "user".

feb 04, 2016 12:20:14 PM com.opensymphony.xwork2.interceptor.ParametersInterceptor error
SEVERE: Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'user' on 'class coproject.cpweb.actions.SaveNewUser: Error setting expression 'user' with val
ue ['{"username":"dd","email":"ff","password":"gg"}', ]
feb 04, 2016 12:20:14 PM com.opensymphony.xwork2.util.LocalizedTextUtil warn
WARNING: Missing key [invalid.fieldvalue.user] in bundles [[org/apache/struts2/struts-messages, com/opensymphony/xwork2/xwork-mess
ages]]!

Any clues on what might be the error?

2
  • 1
    You need to use JSONInterceptor. Commented Feb 4, 2016 at 11:39
  • thanks, i thought the json-default package would already include it. Should I extend the json-default package then? Do you have, by chance, an example of what I should add? Commented Feb 4, 2016 at 11:42

2 Answers 2

2

Extending json-default package doesn't set json interceptor to the defaultStack of interceptors, it just defines that there is such interceptor.

Use interceptorRefs in your @Action annotation to set json interceptor and the defaultStack to the action.

@Action(value="SaveNewUser", 
        interceptorRefs={ @InterceptorRef("json"), 
                          @InterceptorRef("defaultStack") })

Or @InterceptorRefs at the class level to apply interceptors to all actions defined in that class.

@InterceptorRefs({
    @InterceptorRef("json"),
    @InterceptorRef("defaultStack")
})
Sign up to request clarification or add additional context in comments.

11 Comments

I have added this as the annotations to the action ` @Action(value="SaveNewUser", interceptorRefs={@InterceptorRef("json"), @InterceptorRef("defaultStack")}) @ParentPackage("json-default") @Results({ @Result(name="success", type="json"), @Result(name="input", location="/views/error.jsp") }) ` And know no error is shown, but seems the action is not executed. Nothing seems to happen in the server side after the request...
@JoseOspina Try with @InterceptorRefs and w/o interceptorRefs in @Action.
now my eclipse has gone mad and don't detect imports... i will delete .metadata and start over... how fun is that. I will let you know how it goes
=( , implemented with @InterceptorRefs and w/o interceptorRefs in @Action, but the result is the same. Action is not reached and no error is shown in the console
Ok, finally!. Its working. I had an error in the serialization. The X thing after "data: X", within the Ajax call must be a string of the whole object. This is '{"user":{"username":"user","email":"mail","password":"pass"}}' Then, instead of adding the interceptor to the class, I have created, in struts.xml, a new package, with a new interceptor stack (with json and defaultStack), and set as default interceptor stack of that package.
|
0

I was also stuck with the same error, and it was a silly mistake while using POSTMAN, the Body type should be set to JSON, for me the default option of TEXT type was selected.

Provided I used the JSON Interceptor.

<action name="sample" class="com.wildcard.action.SampleController">
            <interceptor-ref name="json"/>
             <interceptor-ref name="defaultStack"/>

<!-- declarations for mappings from Request JSON Body goes here-->
            <result type="json">
                <param name="root">key_from_json_body</param>
            </result>
        </action>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.