Friday, December 28, 2012

Moved to frameworkhell.com

I'm no longer updating this blog, but instead will be using my own site at frameworkhell.com, which will still have some Java stuff but lately it is a lot of Flex and AS3! Some python will get throw in as well. My github account is here.

Saturday, July 7, 2012

jQuery: Binding events dynamically for easy form validation

So often times you have a big form where you need to validate each field individually. Using the $.each () function provided in the jQuery library you can easily loop through an array of Ids and bind events to each one. If you want to do it manually you will have to use a closure (see here).

So lets say you have a big form and a list of text boxes on that form. You probably want to check for several things but you may first of all want of your fields to check for length. So lets make a form that will have error sections after fields. In here we can give the user messages about each text box.


<form type='post' action=''>
<table cellpadding='10'>
    <tr>
        <td>First Name:</td>
        <td><input type='text' name='first_name' id='firstname' /></td>
        <td><span id='firstnameerrors'></span></td>
    </tr>
    <tr>
        <td>Middle Initial:</td>
        <td><input type='text' size='3' name='middle_name' id='middlename' /></td>
        <td><span id='middlenameerrors'></span></td>
    </tr>
    <tr>
        <td>Last Name:</td>
        <td><input type='text' name='last_name' id='lastname' /></td>
        <td><span id='lastnameerrors'></span></td>
    </tr>
</form>







Now for the JavaScript: we need to make an array for each piece of data we need (make sure that these arrays are parallel). We need an array to hold the IDs of each textbox, the IDs of each error span, and finally the things to validate for on each textbox. I made a max length array, and we will count the length of the current value of each of the text boxes. We will then compare against values in the list and display either the count or an error message.



<script type='text/javascript'>
    $(document).ready(function() {
        // section for active validation
        var arrFields = ['#firstname', '#middlename', '#lastname'];
        var errorFields = ['#firstnameerrors', '#middlenameerrors', '#lastnameerrors'];
        var minLengths = [1, 0, 1];
        var maxLengths = [20, 1, 30];
                      
        // This is the special loop with an automatic closure:
        $.each(new Array(arrFields.length),function(i) {
          
            // pull out each thing we need from the iterator.
            var field = arrFields[i];
            var error = errorFields[i];
            var maxlen = maxLengths[i];
          
            //console.log("Binding: " + field + " to error:" + error);
          
            $(field).bind("keyup", function() {
                console.log("firing for: " + field);
                var f = $(field).val();
                var lenField = f.length;
                console.log("length: " + lenField);
              
                $(error).empty().append(lenField + "/" + maxlen);
                if(lenField > maxlen) {
                    $(error).empty().append("Too long!");
                    }
                }); // end bind
              
        });// end loop
      
        // section for submission validation
    });
  
</script>



Now, every time you type into any of the fields in the ID array, an event will fire for each one, providing whatever dynamic validation you have programmed in.

Remember you need to jQuery libraray to make this work. I would recommend using google's CDN for this:


        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>

By the way, here is a full length example using the jquery $.each() loop on my github.


Sunday, June 17, 2012

Installing Tomcat 6 on Linux Mint 12

So I found out today Linux Mint 12 has no default .bashrc file. The Tomcat startup and shut down scripts require a few environmental variables to be set so you will need to create a .bashrc file in your home directory. Then add these lines:

export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
export JRE_HOME=/usr/lib/jvm/java-6-openjdk/jre
export CATALINA_HOME=/home/ard/installedMODULES/apache-tomcat-6.0.35

Take note that these will all be different on your system. Java will likely be in close to the same place, but Catalina Home will wherever the Tomcat folder is located on your disk. You can also add something like this:

alias testing='ls -la'


And if you can run that alias in a new bash shell, then you know bash is importing your settings from .bashrc...

Now all you have to do is go to CATALINA_HOME/conf/tomcat_users.xml which currently should be empty, and add a manager:

<tomcat-users>
  <role rolename="manager"/>
  <user username="root" password="test" roles="manager"/>
</tomcat-users>

Finally, you can start up Tomcat by executing CATALINA_HOME/bin/startup.sh


Saturday, June 16, 2012

Escaping HTML in JAVA using Apache Commons Lang

Anytime you display data that a user entered on a public site you should escape the data to prevent Javascript injection attacks. Here is a cool site with a multitude of possible injections: ha.ckers.org

To escape text you display you can use the Apache Commons Lang library for Java. You can head over to the official site to download the binary and add the JAR files to your project. Once done escaping data is super easy:
<%@page import="org.apache.commons.lang3.StringEscapeUtils"%>

 <%
        String attackScript = "<IMG SRC=javascript:alert('XSS')>";
        String results = StringEscapeUtils.escapeHtml4(attackScript);
        out.print(results);
%>

That is all there is too it. Works just like html_entities() in PHP.  Finally, the documentation for the package is here.

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.


Access Request parameters from Struts 2 Action.

So you want to access the Request object from a Struts 2 Action. Maybe you want the User's IP address or maybe you want the Hostname?

Add these two imports:

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;





And then pull it up like so:


HttpServletRequest request = ServletActionContext.getRequest();
String ip = request.getRemoteAddr();

Monday, June 11, 2012

GET requests with Struts 2

So with Struts 2 when you activate a .action URL that is mapped in the framework, it is no problem at tack on request variables in the URL that will then get passed to a .jsp page or what have you. So here is an example of handling this in the Struts 2 framework:

This is where I generate the URL (e.g. it will look like: 'CodeSnipetById.action?codeid=5')


<table>
        <%
        Session s = HibernateUtil.getSessionFactory().getCurrentSession();
        s.beginTransaction();
      
        CodeSnipet snipet = new CodeSnipet();
        Criteria c = s.createCriteria(CodeSnipet.class);
      
        c.addOrder(Order.desc("idcodesnipets")).setMaxResults(20);
      
        out.print("<tr>");
        out.print("<td>Name</td>");
        out.print("<td>File</td>");
        out.print("<td>Date</td>");
        out.print("</tr>");
        List l = c.list();
        for(Integer i = 0; i < l.size(); i++) {
            snipet = (CodeSnipet)l.get(i);
            String linkBegin = "<a href='CodeSnipetById.action?codeid=";
            String linkEnd = "'>";
            out.print("<tr>");
            out.print("<td>" + linkBegin + snipet.getIdcodesnipets().toString() + linkEnd + snipet.getCodetitle() + "</a></td>");
            out.print("<td>" + snipet.getCodefilename() + "</td>");
            out.print("<td>" + snipet.getStamp().toString() + "</td>");
            out.print("</tr>");
        }
        %>
        </table>
So then within your struts.xml file your action will look like:


          <!-- this goes to show snipet, just with a GET request parameter! -->

                    <action name='CodeSnipetById'>
                        <result>/hibernateTesting/showSnipet.jsp</result>
                    </action>



Finally, in the JSP page that handles this, you will pull the data in via request.getParameter("stringparametername"). If your request is not set it will return 'null' so you can test for a null value like you would test with isset($_GET['whatever']) in PHP. Here is an example of handling the get request and passing into hibernate to pull up some records:


       Session s = HibernateUtil.getSessionFactory().getCurrentSession();
        s.beginTransaction();
        CodeSnipet snipet = new CodeSnipet();
      
        if(request.getParameter("codeid") == null) {
            Criteria c = s.createCriteria(CodeSnipet.class);
            c.addOrder(Order.desc("idcodesnipets")).setMaxResults(1);
            List l = c.list();
            snipet = (CodeSnipet)l.get(0);
            }
         else {
            try {
                Integer myId = Integer.parseInt(request.getParameter("codeid"));
                snipet = (CodeSnipet) s.get(CodeSnipet.class, myId);
            } catch (Error e) {
                Integer myId = 1;
                snipet = (CodeSnipet) s.get(CodeSnipet.class, myId);
                }           
            }


Our 'snipet' object is the Bean we pull the data from.