简体   繁体   中英

How to let struts2 only validate on POST

for example, I have an add method, which in "get" show a form

and in "post" do the add logic, that is validate, call service method and etc.

in the "get" phase, I don't want validate

but the struts2 always validate in those two phase.

How can I config struts2 to only validate on "post" ?

Forget about the REST behavior call the same URL and do different things basing on the Http verbs you are used to:

@RequestMapping(value = "/foo", method = RequestMethod.GET)
public ModelAndView ReadFoobar(Locale locale, 
                               Model model, 
                               HttpServletRequest request){
    String foobar = getService().loadFoobar();
    ModelAndView mav = new ModelAndView("foobarPage")
    mav.addObject("foobar",foobar);
    return mav;
}

@RequestMapping(value = "/foo", method = RequestMethod.POST)
public String InsertStuff(@RequestParam("stuff") String stuff,
                          Locale loc, 
                          Model model,
                          HttpServletRequest req){
    validate();
    getService().insertStuff(stuff);
    return "stuffPage";
}

That is Spring MVC, this is Struts2. You need to reason in terms of Actions; instead of working with Http verbs, use different Actions and define the validation for only one of them. For example:

Action representing GET

public class ReadFoobar {

    @Getter private String foobar;

    public String execute(){
        foobar = getService().loadFoobar();
        return SUCCESS;
    }

}

Action representing POST

public class InsertStuff {

    @Setter private String stuff = "";

    public String execute(){
        getService().insertStuff(stuff);
        return SUCCESS;
    }

    public void validate(){
        if (stuff.length()<3){
            addFieldError("stuff","The mininum length is 3");
        }
    }
}

At this point, associate your readAction only to GET requests:

<s:a action="ReadFoobar">check out this Foobar</s:a>

and insertAction only to POST requests:

<s:form action="InsertStuff" theme="simple">
    <s:textfield name="stuff" />
    <s:fielderror fieldName="stuff" />

    <s:submit value="Insert the stuff" />
</s:form>

You can do the same with XML Validation by specifying a different XML file for each Action class; You can also have two methods in the same Action class, and specify different XML validation (or no validation) at method level, by renaming the XML with the method name after the action name.

Finally, if you still want to be SURE that absolutely no requests, even when cratfed to bypass your UI, can reach eg. ReadFoobar in GET mode, you can write a simple Interceptor (or two if you don't want to pass GET / POST as parameter) and apply it to the desired Action(s).

Eg. write a BlockGetRequestsInterceptor that will block all the GET requests, and apply it to InsertStuff Action (either by struts.xml or with annotations, if using the Convention plugin, that I recommend):

public class InsertStuff {

    @Action(interceptorRefs={
        @InterceptorRef("BlockGetRequestsInterceptor"), 
        @InterceptorRef("defaultStack")})
    public String execute(){
        getService().insertStuff(stuff);
        return SUCCESS;
    }

    // ... 

I like Spring MVC too, but IF you want / need / are using Struts2, use it the right way, the way it is designed for, otherwise it could turn into a nightmare ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM