The Java-Only Web Application (Part II)
In my previous post I described that I wanted to try a pure Java web application. In particular I wanted to avoid angle-bracket programming (aka XML-programming). And I did not want to replace the angle brackets by '@'-programming. So no JSPs or similar and no Spring.
I described already the servelet engine and how to create the HTML without JSP. Further ingredients follow now:
URL parameters get into the servlet like
but there are several pitfalls to avoid when dealing with them:
- The parameter may not exist, if only because a user has
manually trimmed the URL. In this case
- A parameter of the given name may exist several times in the
URL. This may or may not be required by the application. If it
is, we would have to use
- The parameter may be available but not parseable. For example an integer value is expected but the parameter does not parse as an integer.
- Finally the parameter may be parseable but does not fit logically to other parameters or the state of the application, like a negative value when a non-negative is needed.
But this is not all there is to parameter handling. Getting
them in from the URL is only one side of the coin. The other is to
write them out to URLs and form parameters. To handle all this, I
use a rather simple but effective class called
UrlParam<T>. It is
immutable and captures three pieces of information as can be seen
from the constructor:
UrlParam(String name, TYPE value, ParamCodec<TYPE> pCodec)
We have the name of the parameter in the URL, a default value and a codec which translates back and forth between the value type and a string representation. Further, the class has methods to convert from the request and into a URL or a form parameter.
UrlParam<TYPE> fromFirst(ServletRequest req); String getForUrlParam(); String getForInputParam();
The latter two take care of the necessary URL or HTML encoding
on top of the conversion provided by the codec. A few example
codecs which wwere written easily are for
values (a no-op),
Integer values, not forgetting to catch
NumberFormatException, boolean, enums
A tricky part I am not yet completely decided on is whether I
null or a special value as the default value of a
UrlParam to signal the complete absence of a value,
when even a real default does not make sense. I tend more and more
to never use
UrlParam is immutable, it turned out that statically
initializing a template for each parameter was just right. It is
then used at the start of a
doPost() to parse from a request parameter and later
to fill either URLs or form parameters.
Validation of parameters can sometimes be done only piecemeal:
is the parameter an integer, is it an existing user id, is the
next parameter the name of a list, does the user with the id have
access to this list, is the value he wants to enter valid for the
list, etc. The validation needs to take into account complex
dependencies of between the parameters only relevant for this
particular servlet. And the way to handle errors changes depending
on how far we get through the validation, which is why a simple
yes/no decision is not sufficient. This is typically handled at
the start of a servlet request method. Only when the control flow
gets past the last validation step, either the view is created (
doGet) or the model is changed (
Currently I am using H2 as the database in embedded mode. It comes with an easy to use connection pool.
For SQL generation I use JOOQ rather than anything JPA. The reason is that the application's focus is on manipulating the contents of the underlying database, not on using it as an object store. I don't want to abstract away from the fact the my data is in a database. On the contrary, I want to use the database as a database.
In a further blog post I want to describe the security model and access rights and what I learned from implementing it.