Friday, August 17, 2012

Spring MVC - Convention over Configuration w/o Confusion?

Convention over configuration is an essential feature of Spring MVC and it does save some unnecessary coding effort, but I have more than one case where it can get really messy debugging issues.
Here is a simple example: URL app/contact - worked before invoking list method as the only GET method w/o any method level mapping - catch all after the controller mapping.

Beginning 3.1 it will not & throws a 404. But app/contact/list works & will invoke this GET method (IRRESPECTIVE OF THE METHOD NAME), as long it is the only catch-all GET method.

So you could even name it as fooBar and the same URL will invoke it. If however you get confident that the catch-all GET method will always be called for the GET and the URL won't matter, you are right but then the RequestToViewNameMapping goes out the window for the desired view; instead it will look for foorBar.jsp
Something to watch out for!
@Controller
@RequestMapping("contact")
public class ContactController{

@RequestMapping(method = RequestMethod.GET)
 public List<contact> list() {
  logger.info("default method list");
  return contactService.list();
 }
}
Note the mapping generated for this method: INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/contact/*],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.util.List com.aj.recipes.web.ContactController.list()

Wednesday, August 15, 2012

Spring Converter/ConversionService Example

Spring MVC provides so many cool features to make the controller code as minimal as possible. Converter & the ConversionService is one such feature that will be invoked by the framework to carry out type conversions. I have been looking for a decent example & stackoverflow came to the rescue.

I want to add some more information to the solution. As per the Spring documentation here a URI template variable gets translated to the target object using the Converter/ConversionService. I tried to use a `@RequestParam("id") @ModelAttribute("contact") Contact contact`, but I was getting an `IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute` for not having the model object `contact` in my view edit.jsp. This can be easily resolved by declaring a `Model model` and `model.addAttribute(contact);`. However, there is an even better way; using the URI template variable. It's strange why `@RequestParam` did not work. DID NOT WORK
    @RequestMapping("edit") //Passing id as .. edit?id=1
 public String editWithConverter(@RequestParam("id") @ModelAttribute("contact") Contact contact){
  logger.info("edit with converter");
   return "contact/edit";
 }
WHAT WORKED
    @RequestMapping("edit/{contact}") //Passing id as .. edit/1
 public String editWithConverter(@PathVariable("contact") @ModelAttribute("contact") Contact contact){ // STS gave a warning for using {contact} without @PathVariable 
  logger.info("edit with converter");
   return "contact/edit";
 }

So what does this thing do
.. a link like `...edit/1` implicitly invokes the converter for String '1' to Contact of id '1' conversion, and brings this contact object to the view. No need for `@InitBinder` and since its a `Converter` registered with the `ConversionService` I can use this **anywhere I want - implicitly or explicitly**.

Converter:
public class StringToContactConverter implements Converter <String, Contact > {
 private static final Logger logger = LoggerFactory
   .getLogger(StringToContactConverter.class);
 @Autowired
 private ContactService contactService;
 public void setContactService(ContactService contactService) {
  this.contactService = contactService;
 }
 @Override
 public Contact convert(String id) {
  logger.info("Converting String to Contact");
  Contact contact = contactService.getContact(Long.parseLong(id));
  return contact;
 }
}
Configuration: servlet-context.xml
<annotation-driven conversion-service="conversionService"/>

<beans:bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" >
<beans:property name="converters">
<beans:list>
<beans:bean class="com.aj.recipes.web.convert.StringToContactConverter">
</beans:bean></beans:list>
</beans:property>
</beans:bean>

Thursday, May 3, 2012

Javascript Constructor & Namespacing

Namespacing is an obvious requirement for any JS applications in the enterprise world - apps. with several functions & data sets. Keeping data/functions i.e., objects in the global namespace would otherwise require being very creative with var names.
The following code demonstrates how to create a name space as well as constructors for JS Objects.

var a = {};
a.b = {};
a.b.C = function(){
    console.log("Constructor called!!");
    this.value="a.b.C";
    this.toString = function(){return this.value};
}

//console.log(b) // ReferenceError: b is not defined
console.log(a.b) // Object { C=function()}

var aa = new a.b.C();
console.log("Value: " + aa.toString()); // Constructor called!! 
                                        // Value: a.b.C

Thursday, April 5, 2012

ToDo App - jQuery UI

I have been playing around with Jquery UI and finally got some time to create a stand alone app. It's a GTD like app, of my personal taste. I use it home/work for personal tasks management. It may eventually hit the Chrome store, but I need to iron out some more kinks. I used to use task on cygwin, see my blog on this, but it certainly lacks in UI.

Features Include:
  • Uses jStorage for local storage: So tasks are available even after browser restart.
  • Keyboard Shortcuts - q  and Q to either quickly add a task or a form driven interface. Quick Add (q) follows some cryptic format but lets users "quickly" add a task. e.g., Something important ^t @Work #Feb 5 !H
  • Today/Next/Someday - Tabs can be navigated using arrow keys. 
  • Sortable tasks - This is the jquery ui sortable; lets users drag the tasks based on the order in which they want to perform.
  • Completed Tasks get nicely stricken out for that sense of accomplishment :D
Few enhancements that are still in the making:
  • Allow drag-n-drop across panes.
  • In-place editing of tasks : description/context/due/priorities
  • Log of completed/deleted tasks
This app was inspired by the so many good GTD apps available on Chrome Store or Mac OS X & the iOS. 

Friday, March 23, 2012

Unix sed - Fun at Work - Its Friday!

In my constant pursuit of efficiency vis-a-vis laziness, I ended up writing this stream editor command. I needed to transform this long list of constants in java into an HTML select tag. This served as a perfect opportunity to use sed.
Input: This comes from my file.
public static final String SOME_CONSTANT_1 = "CST1";
public static final String SOME_CONSTANT_2 = "CST2";
Output:


Here is the magical command.
sed -e 's/[[:space:]]\{1,\}/ /g' \                                                    
-e 's/.*g[[:space:]]\(.*\);/\1/g' \                                                   
-e 's/\(.*\)[[:space:]]*=[[:space:]]*"\(.*\)"/<option value="\2">\1<\/option>/g' \ 
fileName
  • [1]: Replace multiple spaces/tabs [white spaces] in and around a line in a file with a single space.
  • [2]: Get rid of unnecessary text
  • [3]: Swap and format the output to HTML

Friday, March 16, 2012

Javascript Singleton Pattern

This is just a working example of the idea discussed here. I thought it would help to see the working behavior.
var QuickDialog = function(){
    var privateInit = function(){console.log("init")};
    return{
        init: privateInit
    };
}();

QuickDialog.init();
QuickDialog.privateInit();
This is the firebug output for the above code.

Javascript === vs ==

=== also looks at the type


var a = "1";
var b = 1;
console.log(a===b); //false
console.log(a==b); //true

Saturday, February 18, 2012

Spring MVC 3.1 - Cancel button

I was searching for a way to deal with cancel button that would not cause a form submit and subsequent unnecessary validation of the form backing bean.
I ended up with the following solution for the time being.

Controller:
@RequestMapping(value = "cancel"
 method = RequestMethod.GET)
public String cancelSaveContact() {
 return "redirect:list";
}
JSP:
<a href="<c:url value='/contact/cancel'/>">
 <input type="button" value="Cancel"/>


Update: Unless you don't need cancel to do anything specific for this page, you might as well just redirect to the previous page.

Thursday, January 19, 2012

Java Lessons [3]


3. Hibernate:
People have been forever zealous about jumping into new technologies, but still hanging on to obsolete ideas. Just noticed a code written for Hibernate, where HQL was formed appending several HQLs & then the parameters as well. I thought we were done with this, having identified security issues like SQL injections & the complete failure in utilizing any caching mechanism offered by Hibernate or event the database.
Use Criteria to handle these dynamic queries, at least it will be clean and secure. And Hibernate can even cache these internally, if not by the DB.

Java Lessons [2]


2. Program Flow: 
Noticed another archaic coding style, apparently when there were no methods, where a single call had a ton of if..else.. handling the same condition. Why not branch off at the first if..else..?
This should be obvious by now, but isn't.

Wednesday, January 18, 2012

SOPA - Democracy vs Capitalism

This could be a possible test of the role of Democracy in Capitalism. Whether the people protesting against SOPA or Hollywood et.al sponsored bill, triumph?

I support artist's copyright, but don't support excessive governance. It will just be abused and it will intervene with freedom to share things. Why is internet any different from letting people borrow CD/DVD/BD  books or other copy righted material offline? Isn't this another ploy to make people pay even more than they already do. I think copyrighted material should be freely available after it has lived its glory days. Something, like brand vs generic drugs. Just put a label - "Free after 1yr". Just a suggestion!

But I am certainly against excessive governance/rules, it stifles growth. Fear can never lead us in the right direction. Do we want responsible people or opportunistic thugs?

Wednesday, January 11, 2012

Subversion Notes

1. Sharing library files among projects:
I discovered a nice way of managing the SVN repository where the library files need not be duplicated for every project. I started a bare bone project with the lib files and imported them into the trunk. Now any project that reuses these library files, only has to branch of this trunk and add its own files. Thus, the lib files remain just in the trunk and need not be checked in for every project that uses the files.
e.g.

ext-4.0 only exists in the trunk, a virtual copy exists in braches.

Next, I will explore svn:externals. Supposedly takes care of this shared files/project issues.

I am using svn 1.7.2 installed with cygwin/windows xp and Tortoise. Note: Apparently tortoise takes over the repository and svn command line seems to fail.

Java Lessons

1. Comments vs Naming Conventions:
Method names could be indicative of the operation but not a substitute for comments. There is perennial debate on whether we need java doc - comments vs choosing the succinct approach of choosing the right naming convention and yet I have increasingly found some archaic code that tries to use a method name to contain the entire description which could have been a comment.