Archive for the ‘Spring’ Category

Generic OGNL Controller without Spring WebFlow

January 22, 2007

While working on various web projects many times I felt guilty for writing controllers that perform one-two rows of the code.
It must be easier way! And when I read and tried Spring WebFlow I really liked their approach for defining how to call methods on any exposed bean.
It is what I was looking for. Simple things made easy inside the xml config:

 <bean-action bean="cartController" method="changeQuantities">

 	<method-arguments><argument expression="flowScope.viewCommand"/></method-arguments>

 	<method-result name="viewCommand" scope="flow"/>

 </bean-action>

However Spring WebFlow has many aspects that would stop you from using it for entire site. Click-around navigation and SWF do not play well together.
So what I need is ability to define OGNL expression in Spring coonfig without using SWF. What looked scarry on first sight turned to be extremely easy task.
I did some prototyping of idea and here is what I got in spring config file:

 <bean id="profileView" class="com.cochlear.mcc.web.GenericFormController">

 	<property name="formView" value="profileView"/>

 	<property name="manager"><ref bean="profileManager"/></property>

 	<property name="viewScript"><value>manager.getProfile()</value></property>

 </bean>

 <bean id="profileForm" class="com.cochlear.mcc.web.GenericFormController">

 	<property name="formView" value="profileForm"/>

 	<property name="manager"><ref bean="profileManager"/></property>

 	<property name="modelClass"><value>com.cochlear.mcc.profile.model.ProfileDTO</value></property>

 	<property name="viewScript"><value>manager.getProfile()</value></property>

 	<property name="postScript"><value>manager.updateProfile(#object)</value></property>

 	<property name="successView" value="redirect:profile.view"/>

 </bean>

Not as clear as in SWF maybe but enough to prove the idea. It is concise, it does the job. You do not have to write FormActions for trivial things.
Here is what I have in GenericFormController:

public class GenericFormController extends SimpleFormController{

 protected Object manager;

 protected String viewScript;

 protected String postScript;

protected Object formBackingObject(HttpServletRequest request) throws ServletException, InstantiationException, IllegalAccessException {

 	try {

     	if(StringUtils.hasText(viewScript)){

 			OgnlContext context= new OgnlContext();

 			populateOgnlContextCommon(context, request);

 			Object expr = Ognl.parseExpression(viewScript);

 			Object res=Ognl.getValue(expr, context, this);

 			return res;

     	}else{

     		return getCommandClass().newInstance();

     	}

 	} catch (OgnlException e) {

 		e.printStackTrace();

 		throw new ServletException(e);

 	}

    }

protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,

                                    Object commandObject, BindException errors) throws Exception {

Object command = getCommandClass().cast(commandObject);

 	try {

     	if(StringUtils.hasText(postScript)){

 			OgnlContext context= new OgnlContext();

 			context.put("command", command);

 			populateOgnlContextCommon(context, request);

 			Object expr = Ognl.parseExpression(postScript);

 			Ognl.getValue(expr, context, this);

     	}else{

     		throw new ServletException("No postScript specified");

     	}

 	} catch (Exception e) {

 		errors.reject(null, "Error:"+e.getMessage());

 		return showForm(request, errors, getFormView());

 	}

return new ModelAndView(getSuccessView());

    }

protected void populateOgnlContextCommon(OgnlContext context, HttpServletRequest request){

 	  context.put("request", request);

 	  context.put("session", request.getSession());

 	  context.put("user", SecurityContextHolder.getContext().getAuthentication().getPrincipal());

    }

// Getters and Setters here ..

 // ...

}

When I have time I will do something more production grade. For now I just glad to know that it is achievable and quite simple actualy.

DiggIt | del.icio.us

Advertisements

Discovering Spring MVC

August 28, 2006

Spring MVC is not taken seriously jet because of almost absent documentation. For 2.0 version they wrote couple more paragraphs. But still only pages 214-250 devoted to Spring MVC itself. Many features left undocumented.

For my recent project I had to build a form having 6 different sets of fields. Depending on selected value in combo-box I process specific set. The rest of fields are ignored. That was easy to decide but how to tell Spring no to bind some fields?

One approach is to process input manually disabling automatic binding by overriding supressBinding function:

protected boolean suppressBinding(HttpServletRequest request) {
  return false;
}

Will work but leaves whole burden of binding on your shoulders. You do not want that. The other approach is letting Spring know which fields you want to process and which not. Take a look:
(more…)

Generic DAO and more

August 9, 2006

Since Java 5 introduced new generics feature many aspects of our Java coding has changed. DRY approach to many tiers in J2EE soared and become common place. Even such a conservative monsters as IBM come up with nice generic-based patterns. Have a look at this really good article Dont repeat the DAO. They did not invent something new but rather summarised bit and pieces in pretty well done generic DAO. However if you have simple web-based CRUD project you can go even further and generify your managers. Most of the time managers do exactly the same job providing additional wrapper around DAO. So it is the same CRUD as we had in DAO but DataBase -agnostic. So lets have a look at our DAO:
(more…)