9 Steps for dynamic filtering and paging of a JPA Entity

Folks, this isn’t by any means a show of brilliant software engineering, but I didn’t find anything exactly like it in the blogosphere. I have a really basic scenario to solve.  I have a JQuery grid in a jsp with filterable columns which are mapped via Stripes MVC and Spring to a JPA Entity.

The ajax call from JQuery gives me name/value pairs to filter.  It also gives me the row number to begin the page with and how many rows to retrieve.  From this, I can filter the entity list without hard-coding the Predicates or without building a JPQL string.  The following method goes in Spring Repository or where ever you are keeping business logic for entities.

Step 1:  #44 – Get a CriteriaBuilder from the entity manager

Step 2: #47 – Get a Root of type <YourEntity>

Step 3: #49 – declare a collection of Predicates

Step 4: #60 – For each name/value pair, instantiate a new Like Predicate and add it to the list.  Use The % sign around the data for wildcard searching

Step 5: #62 – Add all predicates to the query’s where clause

Step 6: #63 – create TypedQuery from the CriteriaQuery

Step 7: #70 – set the first row for your page

Step 8: #71 – set your max your for your page

Step 9: #72 – retrieve the data

FilterPaging

Advertisements

How Java Control Panel settings blocked my Java Web Start app

Java Web Start is a really handy way of deploying Java client applications through the web.  Often times resources, such as jar files, have to be provided for the app to work.  And if any of those jar files requires access to system resources, then they must be digitally signed.

If any of the jars that need to be signed are not, then the app will not launch.  You will receive the following.

Unable to launch the application

And if you click “Details” you will see which resource was not signed.  “Found unsigned entry in resource”

This is the error some of my users were receiving when they tried to launch my application.  Not all, but some. All my jars were signed.  I checked.   Upon investigation I learned that a setting in the Java Control Panel was preventing the launch.

You launch the Java Control Panel by clicking the Java icon in the Windows Control Panel.  It looks like this:

The setting that concerns this issue is locating under the Temporary Internet Files>>Settings.

The users that could not launch my application did not have “Keep temporary files on my computer” checked.  After checking it, the app launched properly.  I don’t know exactly why this fixed the problem, but it’s fixed and I’m happy.

Simple Authentication Solution with the Stripes Framework

This security solution will probably not stand up to the scrutiny of a JE (Java Expert), but I’m cool with it.  It’s probably all you’re really looking for.  Something basic and simple.  If you’re new to Stripes check out Stripes Quick Start Guide

The solution requires 4 elements:

  1. @DoesNotRequireLogin Annotation
  2. Security Interceptor
  3. Security Action Bean
  4. JSP login form

@DoesNotRequireLogin Annotation

Creating a Java annotation is very simple.  As a RAJP (Regular Average Java Programmer), I was intimidated at first.  What if I’m not smart enough to figure this out?  What will the JEs think?  ARRRG!  Relax.  It’s easy

That’s it.  You have an annotation.  Now let’s see what you can do with it!

Security Interceptor

see Stripes’ documentation on interceptors http://www.stripesframework.org/display/stripes/Intercept+Execution

An interceptor breaks in at a certain stage of the Stripes life cycle.  In this case, we want it to run any time an action is requested so that we can see if the action requires a login.  Then we make a decision.  Either let the request pass through, or do something else.  In this case we’re asking if the Action Bean that is being requested is annotated with @DoesNotRequireLogin.  I set it up that way instead of @RequiresLogin because the only thing that doesn’t require login is the login.  So I annotated that bean with @DoesNotRequireLogin.  Any other bean has to pass the treacherous isLoggedIn method.  Anything that fails this gets returned back to the login screen.  Also notice that we are implementing the Interceptor interface of which the intercept method is required for implementation.

Action Bean

The action bean serves as the controller.  It can be called upon by any page by setting the beanClass property of a form or link.  The @UrlBinding annotation is where you specify why URL will map to this bean.  The default is to go to the login event because it’s annotated with @DefaultResolution.  All this does is forward the request to the login jsp.  The first instance variable is an EJB that handles data access for the login transaction.  The next two are the variables that will be bound to the login form.  The submitLogin method is the event that the login form will call.  Got it?  That was a lot.  You may need to reread and take a closer look at the tiny picture of my code.

Notice that the class has a @DoesNotRequireLogin annotation.  A request to this Action Bean will pass through the security interceptor.  The submitLogin event processes the login form and uses the EJB to decide whether it passes.  If it doesn’t, we add an error message and return the request back to the login screen.  If it passes, it uses the path variable to forward the request on to wherever the user was trying to go in the first place.

Notice the annotations on the userId and password.  This is Stripes super easy way of doing form validations.  It runs the validation before the action event (submitLogin)  is run and will automatically return to your form with errors if they fail.

Finally, you need a logout event.  This returns the loggedIn session attribute back to false and forwards the request back to the login form.  You’ll just need to throw a logout link somewhere in your application.

Login Form

The login page is a very basic login using a handful of Stripes tags.

It’s a little clipped so you don’t see the layout rendering and the closing div and such, but that’s not what’s important here.   I want you to note just a few things.

  1. The form uses Stripes tags instead of regular HTML tags.  You tell it what Action Bean to submit the form to (see beanclass in the stripes:form…this is our security action bean), and then you tell it what event should handle it (see the stripes:submit tag name property…this is the submitLogin event in the security action bean)
  2. When you use Stripes tags for the inputs, Stripes automagically maps the data input to the instance variables in the Action Bean .  The values of the name attributes have to match the variable names in the action bean (userId and password which have to have getters and setters for it to work).  Pretty handy if you’re used to getting stuff out of the Request and setting them into the variables yourself.
  3. Look at the <stripes:errors> tag.  If the security action bean says the login failed or if the input fields don’t pass validation, it forwards the request back to the login screen and displays the errors in the stripes:errors tag.  Simple. Elegant.
That’s it.  Any request that comes into this application will be intercepted by SecurityInterceptor, and if the requested action bean does not have the @DoesNotRequireLogin, it will ask if the person is logged in, etc.  And in our case, the security action bean will be accessed.  It will route the request to the login page.  The form will submit back to the security action bean (and will pass the interceptor) and go straight to the submitLogin event for processing.  If the login should fail, the request will be returned to the login page with an error message that says so; otherwise, it’s on to the application!
Ok, JEs (Java Experts), you’re welcome to cut this into shreds, but the rest of RAJPs are satisfied…at least this one is.

How do I change the JDK home for Netbeans?

I recently upgraded my JDK and I started getting this message when I launched Netbeans.

Cannot locate java installation in specified jdkhome: [some outdated path].  Do you want to try to use default version?

I’m capable of ignoring messages like this for months, but when I tried to start a new Maven web application, it balked.  It’s simple enough to fix, but it wasn’t obvious to me.  So here you go.

Step One

In your Netbeans home directory (for example, C:\Program Files\NetBeans 7.0.1), open up the netbeans.conf in the etc directory (C:\Program Files\NetBeans 7.0.1\etc\netbeans.conf).

Step Two

Theres a property called netbeans_jdkhome.  Change the value to match the JDK you want Netbeans to use (for example, C:\Program Files\Java\jdk1.6.0_25).

Step Three

Save your changes

Step Four

Restart Netbeans

Java 7 (2011) and Java 8 (2012)- “Let’s get the platform moving again.”

Lest there be any doubt of Oracle’s commitment to the Java SE core, Mark Reinholt shared the previously TOP-SECRET projections for future Java SE releases. He shared his wishlist of core language enhancements which I’m quite sure some other blogger (most likely a JE…Java Expert) will cover ad nauseum (thank you, by the way, whomever you are, that will be awesome).  I look forward to be as confused about Lambda’s as I was about Generics.

The reason I am excited, is that I don’t want to believe that Java is becoming a legacy platform…like my first two platforms did (COBOL and Powerbuilder).   I’m sensing a willingness from Oracle to take some bold moves to bring Java into the 21st century of coding innovation.

Bravo!