Dapeng has posted 1 posts at DZone. View Full User Profile

When Framework is Overkill

02.03.2009
| 7000 views |
  • submit to reddit

Recently there have been some hot articles about frameworks: Better Java Web Frameworks and Better Java Web Frameworks: ItsNat. Sometimes I've found that frameworks just make life harder. Recently I was assigned a job to create a company's site from scratch. The requirement is relatively simple, less than 10 static HTML pages, literally no server side processing.

I decided to write a simple mini "framework" to aid my client's designer, instead of adpoting an off-the-shelf web framework.

The idea is pretty much the same as most CMS: to keep a big template out and to only let the user (the maintanence designer) touch the content of the page. Yet, I want to provide flexibility to some degree. For example, at least I wanted to do some simple SEO to every page.

Template:

<html>
<head>
<title>{{title}}</title>
<meta name="description" content="{{description}}" />
</head>
<body>
<div id="head">
... ignored for simplicity...
</div>
<div id="content">{{body}}</div>
<div id="footer">... </div>
</body>
</html>

And with the template, the actual page needs only to provide the information like TITLE, BODY, DESCRIPTION:

e.g., "about-us.html":

{{title}} About Us

{{description}} what ever information that you want search engine know

{{body}} ... here is the real content, ignored for simplicity... 

So I need a ServletFilter to intercept the request and to wrap the response from "about-us.html" and to make any necessary subsititutions.  I search the default servlet's output for anything like {{ABC}} and use "String.replace" to try to replace/insert into the template string. Once all is done, I dump the result to the original response. 

I have included my source code below. The BufferedServletOutputStream class is copy-and-pasted from a Google search result, sorry I couldn't find the author's name:

public class StaticSiteTemplate implements Filter {
private Map defaultParameters = new HashMap();
private String template = "";

@Override
public void init(FilterConfig filterConfig) throws ServletException {
...
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
CapturedHttpResponseWrapper wrapper = new CapturedHttpResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, wrapper);
// find tagString originalContent = wrapper.toString();
Pattern pattern = Pattern.compile( < a
href = "file://%7b//%7B//w+//%7D//%7D"
mce_href = "file://%7b//%7B//w+//%7D//%7D" >\\{\\{\\w +\\}\\}</a >);
Matcher matcher = pattern.matcher(originalContent);
String result = template;
if (matcher.find()) {
ArrayList breakpointList = new ArrayList();
breakpointList.add(new TemplateBreakupPoint(matcher.group(), matcher.end(), originalContent.length()));
while (matcher.find()) {
breakpointList.get(breakpointList.size() - 1).end = matcher.start();
breakpointList.add(new TemplateBreakupPoint(matcher.group(), matcher.end(), originalContent.length()));
}
for (TemplateBreakupPoint tbp : breakpointList) {
result = result.replace(tbp.key, originalContent.substring(tbp.start, tbp.end).trim());
}
} else {// assume all belong to bodyresult = template.replace("{{body}}", originalContent);}
// replace default params
for (String key : defaultParameters.keySet()) {
result = result.replace(key, defaultParameters.get(key));
}
// dump outputbyte[] buffer = result.getBytes(response.getCharacterEncoding());
response.setContentLength(buffer.length);
response.getOutputStream().write(buffer);
}

public void loadTemplate() throws IOException {...}

...
}

You can view my site as a live demo of this approach here: http://www.nwhholdings.com 

Source code.

Published at DZone with permission of its author, Dapeng Liu.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

ist replied on Tue, 2009/02/03 - 3:04am

Some of the Frameworks really scale well like

<a href=http://www.hibernate.org> Hibernate</a>

<a href=http://www.interview-questions-tips-forum.net>Questions</a>

 

Jeff Devis replied on Tue, 2009/02/03 - 4:22am

I think that all the people who lived the era struts 1 are able to create their own framework,

for those who know that a web framework is

1. one  dispather + many action (mvc2)

2. a request to bean "populator"

3. a validator

4. a business tier caller

5. an i18n message/error/label manager

 for these people, working with a home made framework, is more powerful

personally, I have a basic web framework, that I adapt for every project need, I found that this is the only way to exactly fit to the projet complexity

 

and sorry for my very bad english, 

 

 

tezarhtun sue replied on Tue, 2009/02/03 - 6:02am

Very nice try :)

Daniel Lopez replied on Tue, 2009/02/03 - 6:32am

I'm not against one doing his own thing, I created and mantain our own framework since 1998, but you would have accomplished the same thing faster using SiteMesh: http://today.java.net/pub/a/today/2004/03/11/sitemesh.html

In this case, it's no overkill.

Salute!

 

Mileta Cekovic replied on Tue, 2009/02/03 - 8:03am

Very offten.

Ivan Lazarte replied on Tue, 2009/02/03 - 11:36am

I've made this functionality a bunch of times now, it always serves the customer well as noted in the article.  It'd be nice to have this idea included in the jdk, since it's a very simple variable interpolation like people see in ant for example.  

 For myself I made a framework that uses jsps as controllers which can invoke spring controlled beans references via el and generally stays out of the java realm unless you need to.  If needed, there's an etl-aspect to my framework which can load any sql or xml source into objects via xslt.  for web work, you never really need java as an intermediary.  i built my blog on this premise.  about a days work for commenting, and maybe 2 days to debug the openid admin aspect which isn't exposed to the user.

 its not rails, but its the right framework for me.  easy to dip into hardcore java when needed, high-level by default, easily ported to any container, and the most malleable framework i've worked with :)

Sebastian Otaegui replied on Tue, 2009/02/03 - 1:17pm

I dont really see the point on using Java if you are doing a static content site.

there are several CMS softwares that run on php and also you have tools much easier to use like contribute.

furthermore if they are already paying a web designer, why dont they use his skills directly?

David Marquis replied on Tue, 2009/02/03 - 9:17pm

Using a scripting language and a small, low-overhead library could have saved you a lot of trouble.

PHP: Smarty or Dwoo have excellent templating systems which do not require a big setup around them to be quickly functional. Available everywhere PHP is on (which means everywhere, really)

Python: Django has one of the most fantastic templating system around. Availability depends on your hosting environment. 

Java is not always the solution to everything... 

Cheers! 

Scot Mcphee replied on Wed, 2009/02/04 - 2:44am

Is this post irony - or sarcasm? It can't be serious can it? It is titled "when frameworks are overkill" and then proceeds to illustrate its very proposition - contradictorily presented as a positive attribute of the custom framework offered!

IMO Custom frameworks are a lot, LOT, worse than an off-the-shelf approach. Maintenance programmers can find standard information about any standard framework - the thing you've provided is unsupported and requires the maintainer to learn all about your custom framework rather than apply the extensive already existing support networks for pre-existing software.

Let alone the fact as to whether Java is at all appropriate for a  10 static page HTML website. There are many good free open source CMSs that could have done this job far more cleanly (and extensibly), with supporting documentation and forums. As indicated, there are simple languages and web toolkits far more appropriate than the custom framework provided.

Danny Lee replied on Wed, 2009/02/04 - 10:23am

I have couple of questions about your approach:

Why do you call properties files *.html?
Why don't you use some basic template engine like f.e. velocity?
Why do use files to store contens?

 
My expirience is, than some people hack there own stuff, just because they fail to find, evaluate, adopt and use appropriate open source products.

Dapeng Liu replied on Wed, 2009/02/04 - 11:05pm

Woot, coming back from vacation, seeing so many comments

Well technically i would agree that using an off-the-shelf framework is a great idea

and even not using java completely, like using opensource cms or even using PHP smarty etc

 

I have quite a bit of experience with CMS, currently we are supporting 4 sites build upon open source cms (sugar, joomla) and sometimes it is really hard to convince the customers to know that the cms is not build by us but rather setup by us, and they tend to ask all sorts of HOW-TOs on the CMS itself ... i feel like providing free tech support

 

you may have seen the point here, while CMS does provide some great functionalities, the learning curve is pretty big.

 

Ultimately i want something real simple, as in the article, plain variable replace, took me 1 min to teach my maintanence designer how to use it, since then he has been doing all sorts of editings on the site without asking me 1 thing. 

 

for the part of using plain html files, so the maintanence desigenr could open the content directly via FTP (literally admin free, no need admin backend to interface with mysql) 

 

for NOT using php or whatever-u-think-the-most-properiate, it is because, the server is hosting several other web sites on tomcat already, really no point to setup an apahce+php just for the sake of serving 1 static web site ...

 

last but not least thx for the comment 

Danny Lee replied on Thu, 2009/02/05 - 5:50am

@Dapeng

 OK, but you could at least use performant commons StrSubstitutor, rather than code quite slow and lame own Template Processor. Actually, if you solved the problem this way as member of my team, we would have quite a talk. 

Dapeng Liu replied on Thu, 2009/02/05 - 10:08pm in response to: Danny Lee

Thx for the comment again

I have planned about the optimization part, but in the end, i feel somewhat over-engineering for such a small site, if the processor is doing its job at <1ms then what is the actual performance gain for optimzating it to <0.5ms??

 

matt green replied on Tue, 2009/03/10 - 2:22pm

@dannylee The templates are typically parsed only once, and this can be configured at startup of the servlet container if desired. I don't see any performance issue there. You could even use a sloppy parser. After loaded, a parsed template should look like: blob of text , token to process, blob of text, token to process, etc... this could be stored such that NO additional string substitutions are processed.
I have written my own template engine, quite similar to Dapeng's, and that's how I do it.
I think that velocity is bloated. Besides, why do I want to parse my template files? my template files may need to be loadable into an editor that someone from the graphics department uses, you can't do that with a velocity macro file.
For large websites that target javascript enabled browsers, GWT is the way to go. For small websites I like the simple java templating approach.
Having spent a year using JSF in a commercial product, I think JSF is inferior to GWT.
All web technologies are IMHO inferior to Swing for building applications.
But for a simple, small website, a simple template engine is great, since you can always use any java you want for something you might need, like multithreading (PHP doesn't support multithreading).

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.