Introduction
I was asked to, as an introduction example for a new job, to create a project which should:
- be Java Spring based
- use Maven and Twitter bootstrap
- run on Tomcat
- show a page to enter user name and email,
both validated (in case of validation failure it should preserve user entered values in input boxes)
- show a page of entered users
- support non English characters
Background
I'm completely new to Java / Maven / Spring word, so I decided to go through the templates available on the internet. Each and every one of them was missing at least one required feature. So I decided to contribute to the overall mess with my own bit ;)
Using the code
You can find the result of my work in the attached file. I'm going to make a brief description of every important feature, which problems I encountered and how I've solved them.
Problem 0:)
On the internet there are too many of half cooked and rather wrongly named templates which do much less then they promise. OK, finally I've found following template, which is clearly base of my work: https://github.com/dagi/spring-training and from that specifically springmvc subproject. The problem is, doc for it are in Czech language.
Problem 1: Twitter Bootstrap)
This example is not using Twitter Bootstrap. Adding it is not so easy. There are many Maven packages of Bootstrap. One of them is https://github.com/efsavage/Bootstrap-Maven. It promises taglib interface like:
<%@ taglib uri="http://efsavage.com/twitter-bootstrap" prefix="bs"
You can then use the tags as specified in the taglibs.md file. For example:
<bs:button text="Go" />
Looks good, so I started messing with pom.xml of Maven. But Bootstrap in turn requires jQuery. There is efsavage version of jQuery for Maven. I was not able to make Maven happy regarding this jQuery dependency. I got feeling that Maven is not haven at all. Not to mention it is not clear how to get correct css / js into your resulting web page... Well, I'm missing something crucial with this project, should they improve their doc? Who knows, I need to solve my problem.
So there's another bootstrap/jQuery Maven package on http://mvnrepository.com/artifact/org.webjars. Maven is happy about both dependencies, but how to get css / js into web page? Easy, if you know how to do it. I found following solution:
- add Maven dependency on webjars-locator along with dependency on jquery and bootstrap (pom.xml)
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.0.0</version>
</dependency>
2. add code to locate css / js filen into jsp pages (index.jsp)
<link rel='stylesheet' href='<%= org.webjars.AssetLocator.getWebJarPath("css/bootstrap.min.css") %>'>
<link rel='stylesheet' href='<%= org.webjars.AssetLocator.getWebJarPath("css/bootstrap-theme.min.css") %>'>
<script type='text/javascript' src='<%= org.webjars.AssetLocator.getWebJarPath("jquery.min.js") %>'></script>
<script type='text/javascript' src='<%= org.webjars.AssetLocator.getWebJarPath("js/bootstrap.min.js") %>'></script>
Problem 2: Email Validation)
1. add yet another dependency to Maven (springmvc/pom.xml)
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
2. Annotate model's class member by hybernate/email validator (User.java)
@Email
private String email;
Problem 3: Input text localisation
I've put magic filter into web.xml and localised characters are handled correctly. Some people say that jsp and java files have to be saved in UTF-8, I do not know,
this filter seems necessary anyway:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Problem 4: Preserving user entered values in case of validation error)
This had to be fixed by putting following code into editUser.jsp:
<form:form method="post" modelAttribute="user">
<table>
<tr>
<td>Username:</td>
<td><form:input type="text" path="name" /></td>
<td><form:errors path="name" cssClass="red" /></td>
</tr>
<tr>
<td>Email:</td>
<td><form:input type="text" path="email"/></td>
<td><form:errors path="email" cssClass="red" /></td>
</tr>
</table>
<input type="submit" />
<input type="reset" />
</form:form>
There is crucial to use <form:form ... modelAttribure="user">
which must correspond to
modelAttribute
in UserEditFormController.java code:
@RequestMapping(method = RequestMethod.GET)
public String setupForm(ModelMap model) {
model.addAttribute("user", new User());
return "editUser"; }
@RequestMapping(method = RequestMethod.POST)
public String processSubmit( @ModelAttribute("user")
@Valid User user, BindingResult result, SessionStatus status) {
...
}
Conclusion
By giving you my problems and their solution I'm also giving you enough information how whole thing work without loosing time on stating obvious.
At least for somebody who has some extended experience with programming. And it gives you example which works correctly in mentioned areas and not just working somehow.
Points of Interest
I've removed hibernate to store values into database. I've skipped how to configure Maven to directly store resulting war file into Tomcat by using
MVN tomcat:deploy.
There are plenty of tutorials on those subjects, and none of them work for me yet, so I'll update this article when they do.
History