Tuesday, June 12, 2012

Struts 2 built in form Validation tutorial

Struts 2 has built in form validation, here is how you do it:

First lets make a form: (postSomeCode.jsp - I made a little 'pastebin' style web apps to test this.)

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h2>Post some code</h2>
        <s:form action="PostSomeCode">
            <s:textfield name="description" label="Description" size='40' required='true'/>
            <s:textfield name="filename" label="Filename" size='40' required='true'/>
            <s:combobox name='codetype'
                        label='language'
                        list="{'Javascript', 'Java', 'Python', 'C++', 'SQL', 'CSS', 'XML', 'VB.NET', 'PHP', 'Plain Text'}"
                        headerKey="1"
                        emptyOption="false"
                        required='true'
                        />
            <s:textarea name='codetext' label="code" cols="40" rows="20" required='true'/>
          
            <s:submit/>
        </s:form>
    </body>
</html>


Now lets check out our struts.xml config file. I am adding an action to handle this, a page it redirects too on success, and a redirect back to input (the postSomeCode.jsp form) on failure to validate.


<action name='PostSomeCode' class="dbclasses.PostCodeSnipet">
    <result name="SUCCESS">/hibernateTesting/showSnipet.jsp</result>
   <result name='input'>/hibernateTesting/postSomeCode.jsp</result>
</action>


Now let's check out our action class that I'm sending the results of the form too. The class is called 'PostCodeSnipet' (as you can see in the class ref in the action tag) and the class extents ActionSupport. You have to extend the Struts 2 ActionSupport class when you make your action if you want to use the build in validation:


public class PostCodeSnipet extends ActionSupport{
 //code here
}


Now there are Two functions we override to make this happen. First we overide the default empty validate() function to handle validation.


 // Incoming form:
    private String description = "";
    private String filename = "";
    private String codetype = "";
    private String codetext = "";
// note: there are also getters and setters for these that I did not include in this post.


@Override
    public void validate() {
        if(description.length() < 5){
            addFieldError("description", "Title is not long enough.");
        }
        if(filename.length() < 5) {
            addFieldError("filename", "Filename is not long enough.");
        }
        if(codetext.length() < 5) {
            addFieldError("codetext", "You have to post something here!");
        }
    }



So if you have a length in the field that is not sufficient the Struts 2 framework will now direct you back to the original form (it goes to the name='input' that is mapped in the action) with the error messages above the form fields that you defined. Now in my execute() function I can actually process the form.



@Overridepublic String execute() {
      
        Integer codeTypeID = 0; // This will be inserted into DB
        String myCodeType = getCodetype(); // comes from the form, as a string.
        String types[] ={"Javascript", "PHP","XML","Java", "C++", "SQL",                 "Python", "CSS", "VB.NET"}; 
// Note: plain text is missing on purpose!
        Integer typeIds[] = {1,2,3,4,5,6,7,8,9}; // really this could just be i, but I may changes this later to add more.
      
        Boolean flag = false;
        for(Integer i = 0; i < types.length; i++) {
            if(types[i].equals(myCodeType)) {
                codeTypeID = typeIds[i];
                flag = true;
            }
        }
        if(!flag) {
            codeTypeID = 20;
        }

        // clean text:
        if(filename.length() > 100)
            filename = filename.substring(0, 99);//varchar 100
        if(description.length() > 100)
            description = description.substring(0, 99);//Varchar 100
        if(codetext.length() > 65000)
            codetext = codetext.substring(0, 64999); //'Text' type
      
      
        // Prepare the snipet as an object:
        CodeSnipet snipet = new CodeSnipet();
        snipet.setCodetype(codeTypeID);
        snipet.setCodefilename(filename);
        snipet.setCodetext(codetext);
        snipet.setCodetitle(description);

        HttpServletRequest request = ServletActionContext.getRequest();
        String ip = request.getRemoteAddr();
        snipet.setIp(ip);
        Date d = new Date();
        snipet.setStamp(d);
      
        // we need to insert this into DB:
        Session s = HibernateUtil.getSessionFactory().getCurrentSession();
        s.beginTransaction();
        s.save(snipet);
        s.getTransaction().commit();
      
        // if OK
        return "SUCCESS";
    }


I will post all of this to a github repository when it is more finished and looks nicer.


No comments:

Post a Comment