Sunday, February 19, 2012

Spring MVC - Flash Attributes

Latest Spring Framework incarnation (3.1) brought interesting feature called Flash Attributes. It is remedy for the problem mentioned a long time ago, in one of my posts: Spring MVC - Session Attributes handling. This problem can be described in few words: if we want to pass the attributes via redirect between two controllers, we cannot use request attributes (they will not survive the redirect), and we cannot use Spring's @SessionAttributes (because of the way Spring handles it), only ordinary HttpSession can be used, which is not very convenient.

Below you will find an example of Flash Attributes usage, before you start reviewing it, read Using flash attributes section of Spring documentation.

Suppose that we have two controllers: AController and BController, first one will prepare some data and pass to the second using Flash Attributes after the form submission. On the AController we will have something like this:
@RequestMapping(method = RequestMethod.POST)
public String handleFormSubmission(..., final RedirectAttributes redirectAttrs) {
    ...
    redirectAttrs.addFlashAttribute("AttributeName", value);
    return "redirect:to_some_url_handled_by_BController";
}
When the form will be submitted, attribute value will be stored as Flash Attribute named "AttributeName", and thanks to the Spring, will be passed to BController, where it can be used for example in following way:
@Controller
...
@SessionAttributes("AttributeName")
public class SearchCriteriaHandler {
    ...
    @RequestMapping(method = RequestMethod.GET)
    public void handleGetRequest(@ModelAttribute("AttributeName") final SomeType value) {
        ...
    }
    ...
}

Before your handler method will be called, Spring Framework will populate the Model with the available Flash Attributes - at this point value passed from AController will become a model attribute for the BController. Note, that because we also defined this attribute as the Session Attribute, it will be automatically stored for future usage within this controller, after the GET request handling.

Let me say that I was waiting for this feature for the long time, ;)

Related Posts: Spring MVC - Session Attributes handling

Saturday, January 7, 2012

EasyB, Thucydides and Selenium 2 - another BDD example

Today I'll present you quick example of usage for EasyB - BDD framework for Java :), accompanied by Thucydides - amazing tool for ATDD build on top of Selenium 2.

Suppose that you want to leave something for the humanity, after many sleepless nights you finally discover that it will be a movie database, even more: Internet Movie Database. Now, my Friend, you have two ways: you can start writing this service immediately, forgetting about the eating and sleeping ... When you'll find yourself abandoned by all your Friends, and lost completely in the endless code you wrote, without helpful hand from the tests you were too busy (or even worse, too proud) to wrote ... You'll find the path to enlightenment - second way. Slower, but built on rock solid foundations - ATDD, BDD, and maybe even few more acronyms ;)

Before you yell: "Teach me this way!" few words of explanation. I'm not the Master Yoda. I'm still learning, as you do, and will whole my life, but maybe some parts of my daily exercises will help you somehow ...

Back to the example :) - What we do first, is defining the core functionality required by our service, and describing it in EasyB syntax. Note that in this post we will focus on testing service only. Instead of writing the service, we will use existing Internet Movie Database, and verify if it matches our expectations:


What you see is one of the use cases I assumed for the service. How can we bring it to life now? For example, using Apache Maven, if you decide to choose it as a build system for your project, as I did.

What you need is adding to your pom.xml file few lines defining the EasyB plugin (under build/plugins section):


Now we may try to run this scenario and see what EasyB will tell us. We can do it for ex. with:
mvn clean test easyb:test
Report generated by EasyB looks like this one:


Interesting, but the real fun begins with Thucydides usage. First we have to get back to Apache Maven configuration, and change the report type generated by EasyB from HTML to the default one (XML), otherwise there will be nothing to process for Thucydides.


Now we may try to run our scenario in following way:
mvn clean test easyb:test thucydides:aggregate
and start admiring report generated by Thucydides, which looks like this one:

Summary Page
Features Summary
Stories Summary
Story Details
At this point you probably think - Gosh, looks nice, but how it can be useful for me, as the developer?!

Now we get to the clue :) - as you probably noticed, some steps defined in the scenario are in pending state. This is the moment when the Business Management Team role ends ;), and starts our own :), because we, as the Developers, have to implement the tests standing behind the scenarios. :)

You may also wonder if Thucydides role here is beautifying the reports only - of course not! - it shows its potential when we start to implement tests :).

Let's return to our scenario description:


First of all, we group all features and use cases of our application in 3 level structure - Application - Feature - Use Cases (Scenarios):


Now we implement the steps defined in scenario for the system:


and for the user:


And finally the code reflecting pages of the service, for welcome page:


and search results:


After implementing the code standing behind our scenario, we can run it again and compare the results with expectations:

Summary Page
Features Summary
Stories Summary
Story Details
Thucydides by default creates screenshots of tested application on each UI change (it can be changed to document step failures only), which you can see below:

Welcome page opened (Given)

Title search beginning (When)

UI change - Search Type selected

UI change - search query entered

UI change - form submitted

Search results verification (Then)
Quick summary at the end ;) - EasyB looks like the great tool for BDD, even more attractive when accompanied by Thucydides and Selenium 2. The example above is very quick and simple, but maybe interesting for you, if you are still reading my post ;)

Few lectures for the dessert:

Tuesday, September 13, 2011

Modular Web Application based on JBoss Modules

Recently I read Why there is no standard for developing real modular web applications? by Patroklos Papapetrou. Inspired by this article I decided to check JBoss Modules in action. This post describes my experiment step by step.

I've started with following goal in mind - create web application using some service defined by my own JBoss module. Service prepared by me was pretty simple,  I named it Echo Service:


and placed into separate jar file, named echo-api. Then I implemented this service:


and placed the implementation in new jar file, named echo-module. Having in mind that my web application should have knowledge about the service API only, not the specific implementation, I decided to go the way described in Creating Extensible Applications With the Java Platform - that choice required adding to echo-module jar special file under: META-INF/services/warlock.echo.EchoService, holding the "pointer" to the service implementation (fully qualified name of implementing class).

At this point, I've retrieved and unpacked JBoss Application Server 7, stepped into unpacked JBoss, and then into modules directory. In this directory I've added following structure:


Two jar files visible here are mentioned above, module.xml file is the definition of my JBoss Module - named 'warlock.echo', and has following content:


After completion of JBoss Module definition, I've prepared simple Spring Framework based application (which uses echo-api jar only during the compilation of project and doesn't use the echo-module jar at all) with only one Controller:


As you see the Controller returns as response body the result of Echo Service call for some string. Now to the most important part - Echo Service definition in Web Application:


I know, one thing is bothering you :) - how the hell will Echo Service implementation be found if we don't add either echo-api and echo-module jars to the Web Application?!

Well, this is the beauty itself ;) - We just need one more thing - WEB-INF/jboss-deployment-structure.xml file:


This way we tell JBoss - this application depends on the 'warlock.echo' module and the services defined in this module. The rest is pure JBoss Module magic ;)

Lectures for the dessert:

Tuesday, August 16, 2011

JBehave - quick BDD example

After few last months of work on some projects with Spring MVC, Spring WebFlow, and JPA I had to do something else ;) - even for a while ;) - below you may find a results of my small experiments with Behavior Driven Development and JBehave :)

I started with Introducing BDD and What's in a Story? articles by Dan North, and Alex Soto blog entry about Spring Framework, JBehave and Selenium 2 integration.

Then I asked myself: "What I need for the BDD experiment? - The Story :) - I borrowed one from Dan's article What's in a Story?. Suppose that we have an Account, Card bound to this account, and ATM which will dispense some money. In order to get money when the bank is closed, as an account holder I want to withdraw cash from an ATM - this is the story :) - This story will have 3 possible scenarios in my example:


As you see, this story and the scenarios included are written in human language :) - no programming here, it can be written by anyone! OK, but where is the development here?! - Give me few minutes, and I'll explain that :)

Each Scenario consist of 3 steps: Given, When, Then. First one (Given) defines the context of the specific scenario (ex. "the card is disabled"), second (When) defines the event which occurred in this specific context (ex. "the account holder requests 20"), and third one (Then) defines the state of the context after the event processing (ex. "the ATM should retain the card").

Each scenario's step is bound to the Java code responsible for "implementing" it, in our example:


When you look at the @Given, @When, and @Then annotations you'll see that their values are matching the content of scenario steps written in human language - and this is the point where human language used by your Business Development Team meets the "Real Developers" ;)

Now what? - the rest is easy :) - Alex Soto proposed in his article (Spring Framework, JBehave and Selenium 2 integration) that we can use the Spring Framework driven Components for holding the Steps, this is very nice idea, and sufficient in my example (I would worry about it only in multi-threaded environment, because Component build by Spring is a Singleton by default, and that's usually not a good idea in such  environment).

Spring Framework configuration:


We perform the component scan here (which will register bean for our Steps holding class), and define only one bean related to JBehave, configuring its report builder.

Now we need a code which will allow us to run the Story processing as JUnit test:

When you run this test, all scenarios will be verified, and along with the JUnit test result, JBehave report will be produced:

Few links for the dessert:

Saturday, June 25, 2011

JPQL and joins

Have you ever asked yourself if JPQL (Java Persistence Query Language) queries written by you REALLY do what you want, or you just prepare them, commit to the code repository, and forget about them with a little help from pizza and beer ;) ...

Let's take a look at very simple example, we have Person entity:
@Entity
@Table(name = "PERSONS")
public class Person implements Serializable {

    private String firstName;
    private Long id;
    private Person spouse;

    @Column(name = "FIRST_NAME")
    public String getFirstName() {
        return firstName;
    }

    @Id
    public Long getId() {
        return id;
    }

    @OneToOne(optional = true)
    @JoinColumn(name = "SPOUSE_ID")
    public Person getSpouse() {
        return spouse;
    }
...
}
and we want to fetch all persons matching some criteria.

Suppose that PERSONS table has following entries:

ID SPOUSE_ID FIRST_NAME
1 NULL John
2 NULL Mary
3 4 Adam
4 3 Eva

We will build and execute very simple JPQL query:
Query query = entityManager.createQuery(
    "select person from Person person where person.spouse.firstName = 'Eva' or 1 = 1");
Assert.assertEquals("Result list is too small,", 4, query.getResultList().size());
Our JPQL query should return all persons from the database, because of the "1 = 1" expression in where clause. Let's try how it works with different JPA Providers.

EclipseLink (2.2.0) converts our JPQL query into following SQL query:
SELECT t1.ID, t1.FIRST_NAME, t1.SPOUSE_ID 
FROM PERSONS t0, PERSONS t1 
WHERE (((t0.FIRST_NAME = 'Eva') OR (1 = 1)) AND (t0.ID = t1.SPOUSE_ID))
which leads to assertion error:
java.lang.AssertionError: Result list too small, expected:<4> but was:<2>small 
Hibernate (3.4.0 GA) uses following SQL:
select person0_.id as id1_, person0_.FIRST_NAME as FIRST2_1_, person0_.SPOUSE_ID as SPOUSE3_1_ 
from PERSONS person0_, PERSONS person1_ 
where person0_.SPOUSE_ID=person1_.id and (person1_.FIRST_NAME='Eva' or 1=1)
which leads to the same assertion failure.

Only OpenJPA (2.1.0) uses SQL expected by us:
SELECT t0.id, t0.FIRST_NAME, t1.id, t1.FIRST_NAME 
FROM PERSONS t0 
    LEFT OUTER JOIN PERSONS t1 ON t0.SPOUSE_ID = t1.id 
WHERE (t1.FIRST_NAME = 'Eva' OR 1 = 1)
How can we force EclipseLink and Hibernate to use left join? We have to modify JPQL query in following way:
select person 
from Person person 
    left join person.spouse spouse 
where spouse.firstName = 'Eva' or 1 = 1
As you see I've added explicit left join and changed first where clause expression to use this join.
Now JPQL query returns all 4 records regardless of used JPA Provider.