Tuesday, December 20, 2011

How to find the right balance in between functionality and technology

The fundamental goal of each software developer is to build and deliver the right software that satisfies their customers. A software developer that wants to succeed, must be a professional focusing on a positive outcome of the project. He needs to find the right balance between building the right software and building the software right.


Read my article here: http://blog.goyello.com/2011/12/20/software-development-balancefunctionality-technology/

Friday, December 16, 2011

(My) Top 5 enhancements of Spring MVC 3.1

After many months of development Spring 3.1 has been released. The release is shipped with some exciting features like caching abstraction, bean profiles and container configuration simplifications. This release introduced also many useful enhancments to Spring MVC.


Read my full article at GOYELLO blog here: http://blog.goyello.com/2011/12/16/enhancements-spring-mvc31

Sunday, September 11, 2011

Wednesday, September 7, 2011

Pretty Time - timestamp formatting made easy

Today I was looking for an utility to help me with formating timestamps to user friendly string values like: "moments ago", "few minutes ago", "in couple minutes" etc. Why to write my own implementation, when for sure someone already did it before? And did it better? While googling ("pretty+time+in+java") I found Pretty Time library and I tried it out.

Monday, August 1, 2011

5 things I like in Java 7

Java Platform, Standard Edition 7 was finally released. And even though Lambda, Jigsaw, and part of Coin were dropped from Java 7, it still has some features that I belive will speed up and generally improve development of Java applications. The below list is my personal choice.

Thursday, June 16, 2011

Spring 3.1 MVC: xml-free configuration in Servlet 3.0 environment

Starting from Spring 3.1.0.M2 you can configure Servlet Context programatically in Servlet 3.0 environment (Tomcat 7 for example), with no web.xml and no xml at all. This article demonstrate working Hello World example with xml-free web application configuration.

Update: See Spring MVC Quickstart Maven Archetype (no-xml Spring MVC 4 web application): https://github.com/kolorobot/spring-mvc-quickstart-archetype to get started with Spring MVC. The project is actively maintained and just got updated: http://blog.codeleak.pl/2016/01/spring-mvc-4-quickstart-maven-archetype.html

To start with the project I used STS and I created new Template Project (File > New > Spring Template Project > Spring MVC Project). Once the project was created I made some small modification to the POM file:

  • removed Spring Roo dependencies - why they are there - I don't know
  • changed Spring version to 3.1.0.M2 - to have new functionality in place
  • change maven-war-plugin configuration - so the build will not fail on missing web.xml file:
    <plugin>
     <groupid>org.apache.maven.plugins</groupId>
     <artifactid>maven-war-plugin</artifactId>
     <configuration>
      <warname>spring-mvc-3.1-demo</warName>
      <failonmissingwebxml>false</failOnMissingWebXml>
     </configuration>
    </plugin>
    
And to the project structure:
  • remove /WEB-INF/web.xml
Note: It is not required to remove web.xml. If you would like to leave it - make sure it looks like this:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0"> 
</web-app>

Having project fixed it is time to create configuration files. Let's start with web application initializer that will bootstrap Servlet Context and the Dispatcher Servlet:

public class Initializer implements WebApplicationInitializer {
 public void onStartup(ServletContext servletContext)
   throws ServletException {
  AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
  mvcContext.register(MvcConfig.class);

  ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
    "dispatcher", new DispatcherServlet(mvcContext));
  dispatcher.setLoadOnStartup(1);
  dispatcher.addMapping("/app/*");
 }
}
Initializer is going to be automatically bootstrapped by any Servlet 3.0 container. I checked that with Tomcat 7 server. While bootstrapping you will find following log entries:

INFO : org.springframework.web.SpringServletContainerInitializer - Delegating ServletContext to the following WebApplicationInitializer instances: [pl.codeleak.springmvc31demo.config.Initializer@1b4cd65]

Next step is to configure Spring MVC. I do that in following class:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "pl.codeleak.springmvc31demo.web")
public class MvcConfig {
 @Bean
 public InternalResourceViewResolver configureInternalResourceViewResolver() {
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setPrefix("/WEB-INF/views/");
  resolver.setSuffix(".jsp");
  return resolver;
 }
}
@EnableWebMvc annotation used together with @Configuration enables default Spring MVC configuration, equivalent to <mvc:annotation-driven /> . With @ComponentScan annotation we make sure our @Controller will be added to the application context. The configuration class also defines one @Bean: our default view resolver.

The @Controller generated from template I leave with no changes:

@Controller
public class HomeController {
 
 private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

 @RequestMapping(value = "/", method = RequestMethod.GET)
 public String home() {
  logger.info("Welcome home!");
  return "home";
 }
}

Now it is time to run our Hello World example on Tomcat 7 server and see immediate result in the browser:

Hello World!

I must admit I like recent configuration changes in Spring MVC. It is easy to bootstrap the application with no xml files in place. Of course, this is not everything that Spring MVC 3.1.0 brings to the developers. To see more details checkout this post: http://blog.springsource.com/2011/06/13/spring-3-1-m2-spring-mvc-enhancements-2

You may be also interested in getting started with Spring Boot and Thymeleaf using Maven. Spring Boot is a great piece of software allowing you to bootstrap Spring application within a few seconds. Check this post: HOW-TO: Spring Boot and Thymeleaf with Maven

Thursday, April 28, 2011

Spring Security 3.1: Enhanced security namespace configuration

Security namespace configuration in Spring Security 3.1 improved. The change that made my life easier is the possibility of using multiple <http> to configure security in web application. Each <http> can now configure separate filter chain for different request pattern. This is very useful when you have a web application that consist of standard web application and the API and you want API to be accessible only with basic authentication. To achieve that in Spring Security 3.1 you need to define security configuration as following:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:sec="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <sec:global-method-security secured-annotations="enabled" pre-post-annotations="enabled" />

    <sec:authentication-manager>
        <sec:authentication-provider>
            <sec:user-service>
                <sec:user name="user" password="user" authorities="ROLE_USER" />
                <sec:user name="api" password="api" authorities="ROLE_APIUSER" />
            </sec:user-service>
        </sec:authentication-provider>
    </sec:authentication-manager>
    
    <sec:http pattern="/app/login" security="none"/>
    
    <sec:http pattern="/app/api/**" create-session="stateless" realm="My application API" >
        <sec:intercept-url pattern="/**" access="ROLE_APIUSER" />
        <sec:http-basic />
    </sec:http>
    
    <sec:http create-session="ifRequired">
        <sec:intercept-url pattern="/app/**" access="ROLE_USER"/>
        <sec:form-login login-page="/app/login" always-use-default-target="false" default-target-url="/app/"
            authentication-failure-url="/app/login?login_error=true" password-parameter="password" username-parameter="username" />
        <sec:logout invalidate-session="true" />
    </sec:http>

</beans>

Each time user accesses /app/api/** url in browser he sees basic authentication login dialog. In case he accesses /app/** he is redirected to the login form.

What is new

Except for multiple <http> elements there some additional changes in above configuration


<sec:http pattern="/app/login" security="none" />

pattern attribute that represents the request URL pattern which will be mapped to the filter chain created by http element and security attribute that when set to 'none', requests matching the pattern attribute will be ignored by Spring Security.

<sec:http pattern="/app/api/**" create-session="stateless" />

create-session attribute has new possible value: stateless which implies that the application guarantees that it will not create a session.

<sec:form-login login-page="/app/login" always-use-default-target="false" default-target-url="/app/" authentication-failure-url="/app/login?login_error=true" password-parameter="password" username-parameter="username" />

password-parameter that is the name of the request parameter which contains the password and username-parameter - the name of username parameter.

References

http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ns-config.html http://static.springsource.org/spring-security/site/docs/3.1.x/reference/security-filter-chain.html#filter-chains-with-ns

Saturday, March 19, 2011

How-To: JSR303 validation groups in Spring MVC 3 wizard-style controllers

Beginning with Spring 3, Spring MVC has the ability to automatically validate @Controller inputs. To trigger validation of a @Controller input, simply annotate the input argument as javax.validation.Valid.

Simple. But there is one drawback with automatic validation: using JSR303 validation groups is not possible. A group defines a subset of constraints. Instead of validating all constraints for a given object, only a subset is validated. Each constraint declaration defines the list of groups it belongs to. To trigger group validation group class or classes need to be passed to the validator. As mentioned, validation is triggered by with @Valid annotation. and there is no way you say which validation groups should be used in validation of @Controller input parameter. Until Spring 3.1 is ready and solves the problem, to utilize JSR303 validation groups manual validation is needed.

Note: Have a look at the follow up post that describes the automatic validation with Spring's @Validated annotation (with the source code on GitHub): Validation Groups in Spring MVC.

In this article I will present easy way of utilizing validation groups in Spring MVC with wizard-style controller example.

The example is hypothetical 3-step account registration wizard. The model class is simply a User.

Model


@Entity
public class User {

 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Integer id;

 @Column
 @NotNull
 private String name;
 
 @Column
 @NotNull
 private String email;
 
 @Column
 @NotNull
 private String password;

 // getters and setters
}

View

The three mentioned steps are:
  • Step 1: Username and Email
  • Step 2: Password with confirmation
  • Step 3: Summary page
Each step is stored in AccountForm bean:

@SamePasswords(groups = { AccountForm.AccountStepTwo.class })
public class AccountForm implements PasswordAware {
 // group interfaces (don't need to be interfaces) to be used by constraints.      
 public interface AccountStepOne{}
 public interface AccountStepTwo{}

 // validation group assignment
 @NotNull(groups = { AccountStepOne.class })
 private String username;

 @Email(groups = { AccountStepOne.class })
 @NotNull(groups = { AccountStepOne.class })
 private String email;

 @NotNull(groups = { AccountStepTwo.class })
 private String password;

 @NotNull(groups = { AccountStepTwo.class })
 private String confirmedPassword;

 // getters and setters
}

For each step the view needs to be created. To each view the same model attribute is passed (accountForm)

In stepOne.jsp only the name and email input is required. And therefore it will be only passed to @Controller on form submission:


<form:form modelAttribute="accountForm" method="post">
    <form:errors path="" element="p" />
    <table>
        <tr>
            <td>Name</td>
            <td>
                <form:input path="username"></form:input>
                <form:errors path="username"></form:errors>
            </td>
        </tr>
        <tr>
            <td>Email</td>
            <td>
                <form:input path="email"></form:input>
                <form:errors path="email"></form:errors>
            </td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Next"></input></td>
        </tr>
    </table>
</form:form>

In stepTwo.jsp password input is required (with confirmation field).


<form:form modelAttribute="accountForm" method="post">
    <form:errors path="" element="p" />
    <table>
        <tr>
            <td>Password</td>
            <td>
                <form:password path="password"></form:password> 
                <form:errors path="password"></form:errors>
            </td>
        </tr>
        <tr>
            <td>Confrim password</td>
            <td>
                <form:password path="confirmedPassword"></form:password> 
                <form:errors path="confirmedPassword"></form:errors>
            </td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Next"></input></td>
        </tr>
    </table>
</form:form>

Summary page is skipped, since it contains only the view of input provided.

@Controller

The wizard functionality is handled by AccountRegistrationWizardController.

@Controller
@SessionAttributes("accountForm")
@RequestMapping("account")
public class AccountRegistrationWizardController {

}

Class is annotated with @Controller annotation. It will be autodetected through classpath scanning. @SessionAttributes defines our form attribute to be stored in session between requests

@Autowired(required = true)
private javax.validation.Validator validator;

Spring injects javax.validation.Validator to our controller. We use validator to validate input parameters manually

@RequestMapping("stepOne")
public AccountForm stepOneAccountRegistration() {
 return new AccountForm();
}

Upong entering "account/stepOne" empty AccountForm is populated to the view

@RequestMapping(value = "stepOne", method = RequestMethod.POST)
public String stepOneAccountRegistration(@ModelAttribute AccountForm accountForm, BindingResult bindingResult, Model model) {
 if (isNotValid(accountForm, bindingResult, AccountStepOne.class)) {
  return "account/stepOne";
 }
 return "redirect:stepTwo";
}

Above method takes a account form bound from the requests - step one form (see stepOne.jsp). It is followed by binding result parameter that is used to register validation errors. Please note that account form parameter is not preceded by @Valid annotation and therefore the automatic validation won't happen. Instead, we provide manual validation by calling isNotValid method. This method takes 3 parameters: object to be validated, binding result to store errors and validation group (AccountStepOne.class) to applied during validation.

The validation method below is created based on the code from org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(Object target, Errors errors). The main change according to original code is that we need to call javax.validation.Validator.validate by passing additional arguments: groups and that is the whole trick.


Set<ConstraintViolation<Object>> result = validator.validate(target, groups);
for (ConstraintViolation<Object> violation : result) {
    // method logic
}

Same steps are performed for the next wizard step. This time constraints in AccountStepTwo.class group are going to be validated:


@RequestMapping(value = "stepTwo", method = RequestMethod.POST)
public String stepTwoAccountRegistration(@ModelAttribute AccountForm accountForm, BindingResult bindingResult) {
 if (isNotValid(accountForm, bindingResult, AccountStepTwo.class)) {
  return "account/stepTwo";
 }

 return "redirect:summary";
}

In the final step we may want to validate the complete AccountForm object. To do so, we call the validator as following:


@Transactional
@RequestMapping("finish")
public String finishAccountRegistration(@ModelAttribute AccountForm accountForm, BindingResult bindingResult, SessionStatus sessionStatus) {
 if (isNotValid(accountForm, bindingResult, AccountStepOne.class, AccountStepTwo.class)) {
  return "redirect:stepOne";
 }
 User user = createUser(accountForm);
 sessionStatus.setComplete();
 FlashMap.setInfoMessage("Account'" + user.getName() + "' created!");
 return "redirect:../user/list";
}

This time we passed both groups to the validator to make sure all fields are going to be validated. If the object is valid, we store it in database and finish the wizard by calling org.springframework.web.bind.support.SessionStatus.setComplete(). Please note that form object is not passed from the form but it is retrieved from the session for us (see complete code)

Summary

In above steps I presented how easy we may utilize JSR303 validation groups functionality in Spring MVC 3 wizard-style controllers. Hopefully, in Spring 3.1 this workaround will not be needed anymore.

Update

Have a look at the follow up post that describes the automatic validation with Spring's @Validated annotation (with the source code on GitHub): Validation Groups in Spring MVC.

References

Downloads

Project created with Maven2 and Eclipse and was tested with Tomcat 7.

Download: bean-validation-springmvc-demo.zip

Follow up

Have a look at the follow up post that describes the automatic validation with Spring's @Validated annotation: Validation Groups in Spring MVC.

Monday, March 14, 2011

Codeleak.pl Started!

package pl.codeleak;  
  
public class Codeleak {  
  
    public static void main(String[] args) {  
        System.out.println("Blog started...");  
    }  
}