Jun 17, 2010

Blank lines in Error messages

For the blank line that is appearing for your action/field messages/errors, this is how you solve it:


  • Update the “.errorMessage” element in mpa.css Change to include the following:

margin-bottom:0px;

  • Change your JSP to hold each of the <s:actionErrors/> <s:actionMessages /> <s:fieldErrors/> in separate rows of your table.

<table cellspacing=“0”>
<tr>
<td>
<s:actionErrors />
</td>
</tr>
<tr>
<td>
<s:actionMessages />
</td>
</tr>
<tr>
<td>
<s:fieldErrors />
</td>
</tr>
</table>

  • Make sure that your table also has attribute “cellspacing=’0’”.

Jun 15, 2010

Aspect J Logging

In order to standardize logging, here are the steps that you need to do..

1) Enter the following into your web.xml:

<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener><listener-class>org.springframework.web.util.Log4jConfigListener</listener-class></listener>

2) Add the following entry to your log4j.properties:

log4j.logger.com.xxx.apps.??=DEBUG
(Replace ?? with your application name)

3) Add the following to your spring.xml file:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
default-autowire="autodetect">
<bean id="log" class="org.springframework.beans.factory.config.CommonsLogFactoryBean">

<property name="logName" value="com.xxx.apps.??" />
<!-- Replace ?? with your application name -->
</bean>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean id="loggingAspect" class="gov.mpa.apps.aspect.LoggingAspect"/>

4) Add the following to your BASE classes:

protected org.apache.commons.logging.Log logger;

public Log getLog()
{
return logger;
}

public void setLog(Log logger)
{
this.logger = logger;
}

5) Add the attached to your project first. This should be bundled together with the common components.

6) Remove all other logging mechanisms.


In LoggingAspect.java


package com.xxx.apps.aspect;

import com.xxx.component.security.spring.web.authentication.preauth.j2ee.userdetails.MPAAuthenticatedUser;

import org.apache.log4j.NDC;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.context.SecurityContextHolder;

/*
* AOP (Aspect Oriented Programming) is a powerful complement to object-
* oriented programming. With aspects, you can now group application
* behavior that was once spread throughout your applications into
* reusable modules.
*
* Using @AspectJ annotation you can turn the pojo classes into aspects
* without the need for additional classes or bean declarations.
*
* Here are the AOP terminologies:
*
* Aspect - is the modularization of concern that cuts across multiple
* classes. It is the merger of the advice and pointcuts.
*
* Joinpoint - is the point during the execution of a program, such as the
* execution of a method or the handling of an exception.
*
* Advice - is the action taken by the aspect at a particular joinpoint.
*
* Pointcut - is a predicate that matches one or more join points at which
* advice should be woven.
*
* Target - is the object being advised by one or more aspects.
*
* AOP proxy - is the object created by the AOP after applying advice to the
* target object. It can either be a JDK dynamic proxy or a
* CGLIB proxy.
*
* Weaving - is the process of applying aspects to a target object to create
* a new, proxied object. The aspects are woven into the target
* object at the specified joinpoints.
*
* This aspect class provides logging support for all matching classes
* defined in the pointcut. By using this class, separation of concern
* is achieved thereby making the business classes much cleaner in
* implementation.
*/
@Aspect
public class LoggingAspect
{

/*
* The @Pointcut annotation is used to define a reusable pointcut
* within an @AspectJ aspect. It indicates that the pointcut should
* match all the methods of any class within com.xxx.apps.meps.service
* package.
*
* Take note that this method is just a marker, giving the @Pointcut
* annotation something to attach itself to.
*/
@Pointcut("execution(public * org.apache.commons.logging.Log.debug(..)) " +
"|| execution(public * org.apache.commons.logging.Log.info(..)) " +
"|| execution(public * org.apache.commons.logging.Log.error(..)) " +
"|| execution(public * org.apache.commons.logging.Log.fatal(..))" )
public void doLogging() {}

/*
* The @Before annotation is used to define an advice that executes
* before the target method of the matching bean is called.
*/
@Before("doLogging()")
public void doPush(JoinPoint jp)
{
XXXAuthenticatedUser user = (XXXAuthenticatedUser) SecurityContextHolder.getContext().getAuthentication();

NDC.push("["+user.getLoginId()+"]["+user.getIPAddress()+"]");
}

/*
* The @AfterReturning annotation is used to define an advice that executes
* after the target method of the matching bean is called successfully
* without throwing an exception.
*/
@AfterReturning(pointcut="doLogging()")
public void doPop(JoinPoint jp)
{
NDC.pop();
}

/*
* The @AfterThrowing annotation is used to define an advice that
* gets executed if a method exits by throwing an exception.
*/
@AfterThrowing(pointcut="doLogging()", throwing="e")
public void doExceptionLogging(JoinPoint jp, Throwable e)
{
//do nothing
return;
}
}

Jun 10, 2010

Struts, Annotations and Mime

To set a dynamic filename in annotated results.

In Action class:

private String date;

//Above the action handling the download:
@Result(name = "success", type= StreamResult.class,
params = {"contentType", "application/vnd.ms-excel",
"contentDisposition", "attachment; filename=report_$(date).xls"},
value = "reportFileStream"
)

//The usual getter/setter:
public String getDate(){
return date;
}

public void setDate(String date){
this.date = date;
}