<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5074672205700443198</id><updated>2011-11-27T18:19:11.710-05:00</updated><category term='logging'/><category term='google app engine'/><category term='reflection'/><category term='proxy'/><category term='sitemesh'/><category term='localization'/><category term='video card'/><category term='tomcat'/><category term='ognl'/><category term='pragmatic programmer'/><category term='http'/><category term='spring 2'/><category term='mime type'/><category term='spring security 2.x'/><category term='browser'/><category term='zope'/><category term='xss'/><category term='http header'/><category term='jackson'/><category term='review'/><category term='struts 2'/><category term='database'/><category term='apache'/><category term='welcome-file'/><category term='hibernate'/><category term='shell script'/><category term='iis'/><category term='mysql'/><category term='ajax'/><category term='security'/><category term='port forwarding'/><category term='ssh'/><category term='log4j'/><category term='plone'/><category term='annotation'/><category term='struts'/><category term='build'/><category term='jpa'/><category term='ie6'/><category term='*nix'/><category term='ssl'/><category term='https'/><category term='caching'/><category term='testing'/><category term='ubuntu'/><category term='velocity'/><category term='web.xml'/><category term='nvidia'/><category term='spring 3'/><category term='json'/><title type='text'>programming panda</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-5589040524510950542</id><published>2011-08-19T10:45:00.004-04:00</published><updated>2011-08-19T12:46:20.734-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jackson'/><category scheme='http://www.blogger.com/atom/ns#' term='spring 3'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><title type='text'>Jackson helps you to "Ajaxify" your Spring service in less than 5 mins</title><content type='html'>You can now turn your Spring service into an ajax service easily with the use of annotation and Jackson&lt;br /&gt;&lt;br /&gt;Let's say you have a service to search for a product, something like this:&lt;br /&gt;&lt;br /&gt;public class productServiceImpl{&lt;br /&gt;&lt;br /&gt;private ProductDao productDaoImpl;&lt;br /&gt;&lt;br /&gt;public List&lt;string&gt; search(String searchString){&lt;br /&gt;  productDao.search(searchString);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;And usually your Spring MVC controller will be something like this&lt;br /&gt;&lt;br /&gt;@Controller&lt;br /&gt;@RequestMapping("/product")&lt;br /&gt;public class ProductController{&lt;br /&gt;&lt;br /&gt;private ProductService productService;&lt;br /&gt;&lt;br /&gt;@RequestMapping("/search")&lt;br /&gt;public List&lt;string&gt; search(@RequestParam("searchString") String searchString, ModelMap model) {&lt;br /&gt;return productService.search(searchString);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;To expose the search service as an ajax service, simply&lt;br /&gt;1. Add &lt;a href="http://jackson.codehaus.org/"&gt;jackson&lt;/a&gt; to your library if you haven't do so&lt;br /&gt;2. Add     &lt;mvc:annotation-driven&gt; to your applicationContext.xml&lt;br /&gt;Remember also add the schema Location&lt;br /&gt;http://www.springframework.org/schema/mvc         http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&lt;br /&gt;to specify the name space&lt;br /&gt;3. add @ResponseBody before the return type in the method as follow&lt;br /&gt;&lt;br /&gt;@RequestMapping("/jsonsearch")&lt;br /&gt;public @ResponseBody List&lt;string&gt; search(@RequestParam("searchString") String searchString, ModelMap model) {&lt;br /&gt;return productService.search(searchString);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;That's it!&lt;br /&gt;&lt;br /&gt;To access this simply send request to&lt;br /&gt;http://localhost:8080/myapp/product/search?searchString=iphone&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/string&gt;&lt;/mvc:annotation-driven&gt;&lt;/string&gt;&lt;/string&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-5589040524510950542?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/5589040524510950542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2011/08/jackson-helps-you-to-ajaxify-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/5589040524510950542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/5589040524510950542'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2011/08/jackson-helps-you-to-ajaxify-your.html' title='Jackson helps you to &quot;Ajaxify&quot; your Spring service in less than 5 mins'/><author><name>roy</name><uri>http://www.blogger.com/profile/01700431226636892208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-480752109013900629</id><published>2011-08-17T10:25:00.000-04:00</published><updated>2011-08-17T10:25:22.024-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><title type='text'>Could not parse configuration: /hibernate.cfg.xml Caused by: org.dom4j.DocumentException: Connection refused</title><content type='html'>&lt;br /&gt;If you every run into the below, &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;org.hibernate.HibernateException: Could not parse configuration: /hibernate.cfg.xml&lt;br /&gt;	at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1500)&lt;br /&gt;	at org.hibernate.cfg.Configuration.configure(Configuration.java:1434)&lt;br /&gt;	at org.hibernate.cfg.Configuration.configure(Configuration.java:1420)&lt;br /&gt;	at org.hibernate.tutorial.hbm.NativeApiIllustrationTest.setUp(NativeApiIllustrationTest.java:47)&lt;br /&gt;	at junit.framework.TestCase.runBare(TestCase.java:132)&lt;br /&gt;	at junit.framework.TestResult$1.protect(TestResult.java:110)&lt;br /&gt;	at junit.framework.TestResult.runProtected(TestResult.java:128)&lt;br /&gt;	at junit.framework.TestResult.run(TestResult.java:113)&lt;br /&gt;	at junit.framework.TestCase.run(TestCase.java:124)&lt;br /&gt;	at junit.framework.TestSuite.runTest(TestSuite.java:243)&lt;br /&gt;	at junit.framework.TestSuite.run(TestSuite.java:238)&lt;br /&gt;	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)&lt;br /&gt;	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)&lt;br /&gt;	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)&lt;br /&gt;	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)&lt;br /&gt;	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)&lt;br /&gt;	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)&lt;br /&gt;	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)&lt;br /&gt;Caused by: org.dom4j.DocumentException: Connection refused: connect Nested exception: Connection refused: connect&lt;br /&gt;	at org.dom4j.io.SAXReader.read(SAXReader.java:484)&lt;br /&gt;	at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1490)&lt;br /&gt;	... 17 more&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;it means that the XML parser is having a problem trying to access your DTD definition.  So first thing to do is to see if you can browse the url for it directly and also check your proxy settings.  In my case, I changed it &lt;br /&gt;&lt;br /&gt;from &lt;br /&gt;&lt;pre class="brush:java"&gt;&amp;lt;!DOCTYPE hibernate-configuration PUBLIC&lt;br /&gt;        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"&lt;br /&gt;        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;to&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;&amp;lt;!DOCTYPE hibernate-configuration PUBLIC&lt;br /&gt;        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"&lt;br /&gt;        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I think you can also try using "http://www.jboss.org/dtd/hibernate/hibernate-configuration-3.0.dtd".  It seems like hibernate.org fwds to the jboss location anyways.&lt;br /&gt;&lt;br /&gt;(as of today....unless the urls change again)&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-480752109013900629?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/480752109013900629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2011/08/could-not-parse-configuration.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/480752109013900629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/480752109013900629'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2011/08/could-not-parse-configuration.html' title='Could not parse configuration: /hibernate.cfg.xml Caused by: org.dom4j.DocumentException: Connection refused'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-3225452622413257097</id><published>2010-03-17T18:58:00.000-04:00</published><updated>2010-03-17T18:58:18.766-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reflection'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>unit testing private methods</title><content type='html'>next time i want to test private methods again, remember the answer to this....&lt;br /&gt;&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/34571/whats-the-best-way-of-unit-testing-private-methods"&gt;Answer in Stack Overflow&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-3225452622413257097?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/3225452622413257097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2010/03/unit-testing-private-methods.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/3225452622413257097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/3225452622413257097'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2010/03/unit-testing-private-methods.html' title='unit testing private methods'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-5886605433014701256</id><published>2010-02-17T21:31:00.000-05:00</published><updated>2010-02-17T21:31:26.726-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caching'/><category scheme='http://www.blogger.com/atom/ns#' term='sitemesh'/><category scheme='http://www.blogger.com/atom/ns#' term='ie6'/><category scheme='http://www.blogger.com/atom/ns#' term='browser'/><title type='text'>DOWNLOADING DOCUMENTS VIA SSL CONNECTION ON IE... part 2 + Sitemesh 2.2.1</title><content type='html'>After doing a code release last week, we discovered that our application had a caching issue since some of the .js files we changed weren't getting loaded properly.  This was a surprise to us since we have html meta tags on each page for no caching and we also have included the no caching directives in our http response headers.&lt;br /&gt;&lt;br /&gt;So what's going on?  it had to do with the matter in which we included the no caching directives in our http response header.  Our site uses sitemesh and we decided to include those directives in our sitemesh main decorator page.  Big mistake, because &lt;a href="http://jira.opensymphony.com/browse/SIM-17"&gt;sitemesh has a bug&lt;/a&gt;, and for some reason, it can't recognize the jsp scriptlets that we used to add the no caching directives.  &lt;br /&gt;&lt;br /&gt;Our solution? provide a filter that sites in front of our application that filters that applies the no caching directives to our secured pages and our javascript resources.  (note, you need to modify the below code before using..  read the rest of the article to see why)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;import javax.servlet.Filter;&lt;br /&gt;import javax.servlet.FilterChain;&lt;br /&gt;import javax.servlet.FilterConfig;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.ServletRequest;&lt;br /&gt;import javax.servlet.ServletResponse;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * adds the no caching directives into the http response header&lt;br /&gt; * see:&lt;br /&gt; * http://en.wikipedia.org/wiki/List_of_HTTP_headers&lt;br /&gt; * http://www.i18nguy.com/markup/metatags.html&lt;br /&gt; * &lt;br /&gt; */&lt;br /&gt;public class NoCachingFilter implements Filter {&lt;br /&gt;&lt;br /&gt; private static final String CACHE_CONTROL_PARAM ="Cache-Control";&lt;br /&gt; private static final String CACHE_CONTROL_VALUE ="no-cache";&lt;br /&gt; &lt;br /&gt; private static final String PRAGMA_PARAM = "Pragma";&lt;br /&gt; private static final String PRAGMA_VALUE = "no-cache";&lt;br /&gt; &lt;br /&gt; private static final String EXPIRES_PARAM = "Expires";&lt;br /&gt; private static final int EXPIRES_VALUE = 0;&lt;br /&gt; &lt;br /&gt; private FilterConfig filterConfig = null; &lt;br /&gt; &lt;br /&gt;&lt;br /&gt; public void init(FilterConfig filterConfig) throws ServletException {&lt;br /&gt;  this.filterConfig = filterConfig;&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {    &lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  HttpServletResponse response = (HttpServletResponse) servletResponse;&lt;br /&gt;  response.setHeader(CACHE_CONTROL_PARAM,CACHE_CONTROL_VALUE);&lt;br /&gt;  response.setHeader(PRAGMA_PARAM,PRAGMA_VALUE);&lt;br /&gt;  response.setIntHeader(EXPIRES_PARAM,EXPIRES_VALUE);&lt;br /&gt;  &lt;br /&gt;  // continue with remaining filters&lt;br /&gt;  filterChain.doFilter(servletRequest, servletResponse);&lt;br /&gt;    &lt;br /&gt;  //note: must be done before else the response is already commited.&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void destroy() {&lt;br /&gt;  filterConfig = null;  &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre class="brush:text"&gt;That was mistake number 2.  After a round of testing, we discovered that some of our file downloads would not work, namely, we ran into this &lt;a href="http://support.microsoft.com/?kbid=323308"&gt;internet explorer bug&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:text"&gt;Internet Explorer file downloads over SSL do not work with the cache control headers.&lt;br /&gt;&lt;br /&gt;This issue may occur if any one or more of the following conditions are true:&lt;br /&gt;The Do not save encrypted pages to disk check box is selected in Internet Explorer 6.0 SP1.&lt;br /&gt;The server sends the "Cache-Control: No Store" header.&lt;br /&gt;The server sends the "Cache-Control: No Cache" header.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Looks familiar?  well this is definitely related to &lt;a href="http://programmingpanda.blogspot.com/2009/08/downloading-documents-via-ssl.html"&gt;my earlier post&lt;/a&gt;.  I guess now, I know the root cause.  I guess I should have also read that article more closely last time.  This part is incredibly interesting since &lt;a href="http://support.microsoft.com/kb/234067"&gt;microsoft themselves recommends&lt;/a&gt; you to use the no cache directives...&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:text"&gt;Are you using the Cache-Control header with the ASP "Response.CacheControl" property or through a returned HTTP header? This is the only way to truly prevent caching in Internet Explorer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;My updated solution modifies my filter to provide an exclusion list so that I don't add any "no caching" directives on downloaded content.  All the other pages will have the protection of "no caching".  If anyone has better ideas, please feel free to comment and share your ideas!&lt;br /&gt;&lt;br /&gt;Appendix:&lt;br /&gt;Here are a list of other references i found related to this problem:&lt;br /&gt;- It seems the the &lt;a href="http://edn.embarcadero.com/article/39141"&gt;issue occurs in ie7&lt;/a&gt; as well.&lt;br /&gt;- a long list of &lt;a href="http://www.colba.net/~hlebo49/downfile.htm"&gt;related issues&lt;/a&gt; or different descriptions of the same issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-5886605433014701256?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/5886605433014701256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2010/02/downloading-documents-via-ssl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/5886605433014701256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/5886605433014701256'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2010/02/downloading-documents-via-ssl.html' title='DOWNLOADING DOCUMENTS VIA SSL CONNECTION ON IE... part 2 + Sitemesh 2.2.1'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-3425255189556681544</id><published>2009-08-26T20:23:00.003-04:00</published><updated>2009-08-26T20:55:41.125-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='http header'/><category scheme='http://www.blogger.com/atom/ns#' term='xss'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>XSS in the HTTP Header's Accept Language when using Struts 1.2</title><content type='html'>At my work, we have a policy of using HP's WebInspect to scan our applications before they are allowed to go into production and I just got an interesting finding this week. The WebInspect scanner tried to perform a XSS (cross site scripting) attack by putting something into the HTTP header's Accept Language!  Now, I'm not really sure how exploitable this is (perhaps some security expert can comment?) since all our traffic is via https, so there's really no way to inject some scripts into the http header unless the host machine making the request has been compromised?&lt;br /&gt;&lt;br /&gt;This was the http request used....&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;GET /programmingPanda/someUrl.jsp HTTP/1.1&lt;br /&gt;Accept: */*&lt;br /&gt;Referer: https:///programmingPanda/someUrl&lt;br /&gt;Accept-Language: "&amp;gt;&amp;lt;script&amp;gt;alert('hi')&amp;lt;/script&amp;gt;&lt;br /&gt;UA-CPU: x86&lt;br /&gt;Accept-Encoding: gzip, deflate&lt;br /&gt;User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)&lt;br /&gt;Host: www.programmingPandaHost.com&lt;br /&gt;Pragma: no-cache&lt;br /&gt;Connection: Keep-Alive&lt;br /&gt;Cookie:&lt;br /&gt;JSESSIONID=0021w1Z_9Fg27Vg1xhKHDgX1YLR:1244ioqb0;CustomCookie=WebInspect30127ZXC16B0&lt;br /&gt;44F25944608B21BBFFEC74B3453YE540&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and the end result was this....&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:html"&gt;&lt;br /&gt;&amp;lt;html xmlns:"http://www.w3.org/1999/xhtml" lang=""&amp;gt;&amp;lt;script&amp;gt;alert('hi')&amp;lt;/script&amp;gt;" xml:lang=""&amp;gt;&amp;lt;script&amp;gt;alert('hi')&amp;lt;/script&amp;gt;"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Anyways, I was tasked with checking this out.  After some digging, I found that the html tag in our application was being generated by the struts taglib's html tag.  According to the &lt;a href="http://struts.apache.org/1.2.x/userGuide/struts-html.html#html" target="_new"&gt;specifications&lt;/a&gt;, it seems that the lang attribute of the html tag has the following behaviour...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Renders a lang attribute with the locale stored in the user's session.&lt;br /&gt;If not found in the session, the language from the Accept-Language HTTP header is used.&lt;br /&gt;If still not found, the default language for the server is used.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So with the Accept-Language not being validated for special characters, we were getting XSS-ed!&lt;br /&gt;&lt;br /&gt;The solution?  In this case, we used a filter to provide a default locale into the user's session if non is detected to avoid using the Accept-Language in the HTTP header.  This may not be the best or most correct solution, but it is one that fits our needs and timeline.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;//provide some default locale and set it into the struts defined attribute, Globals.LOCALE_KEY&lt;br /&gt;session.setAttribute(Globals.LOCALE_KEY, locale);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-3425255189556681544?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/3425255189556681544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/xss-in-http-headers-accept-language.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/3425255189556681544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/3425255189556681544'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/xss-in-http-headers-accept-language.html' title='XSS in the HTTP Header&apos;s Accept Language when using Struts 1.2'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-3479409257152705758</id><published>2009-08-25T15:44:00.006-04:00</published><updated>2009-08-25T16:08:22.633-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ssl'/><category scheme='http://www.blogger.com/atom/ns#' term='https'/><category scheme='http://www.blogger.com/atom/ns#' term='ie6'/><title type='text'>downloading documents via SSL connection on IE</title><content type='html'>&lt;div style="text-align: center;"&gt;I ran into a pretty interesting issue today.  (This is a follow up of &lt;a href="http://programmingpanda.blogspot.com/2009/07/getting-http-405-on-iis.html"&gt;my earlier post&lt;/a&gt; ).  I was trying to download some text file from our application using IE6.  Suddenly I get a very unexpected error:&lt;/div&gt;&lt;pre&gt;Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later.&lt;/pre&gt;&lt;br /&gt;I was super surprised because I was 100% the file was there.  Did some research online, and it seems to be related to this issue&lt;br /&gt;&lt;a href="http://support.microsoft.com/default.aspx?scid=KB;EN-US;q316431&amp;amp;"&gt;http://support.microsoft.com/default.aspx?scid=KB;EN-US;q316431&amp;amp;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_gFblrByuQfw/SpREHd2PQhI/AAAAAAAAEEI/817_7hXN9RY/s1600-h/ie6_error1.jpg" target="_new"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 54px;" src="http://3.bp.blogspot.com/_gFblrByuQfw/SpREHd2PQhI/AAAAAAAAEEI/817_7hXN9RY/s320/ie6_error1.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5373995150421738002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It seems that when you download from an SSL session, and IE6 can't save it temporarily to disk locally, it has issues.  Lucky for me, this is an internal application, and I could just my users to ensure their browser settings are as below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;You can get to here from Tools &gt; Internet Options &gt; Advanced.  Scroll down to the bottom in the Security section. And look for “Do not save encrypted pages to disk”. Make sure this is turned OFF&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_gFblrByuQfw/SpRDiGlsm1I/AAAAAAAAEEA/5_8J2X3UnBk/s1600-h/ie6_setting1.jpg" target="_new"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 179px; height: 200px;" src="http://3.bp.blogspot.com/_gFblrByuQfw/SpRDiGlsm1I/AAAAAAAAEEA/5_8J2X3UnBk/s200/ie6_setting1.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5373994508523182930" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-3479409257152705758?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/3479409257152705758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/downloading-documents-via-ssl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/3479409257152705758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/3479409257152705758'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/downloading-documents-via-ssl.html' title='downloading documents via SSL connection on IE'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_gFblrByuQfw/SpREHd2PQhI/AAAAAAAAEEI/817_7hXN9RY/s72-c/ie6_error1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-9196579185433128695</id><published>2009-08-21T17:35:00.006-04:00</published><updated>2009-08-24T00:03:45.253-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='annotation'/><category scheme='http://www.blogger.com/atom/ns#' term='spring 2'/><title type='text'>Recipe: Spring + JPA Annotation + Hibernate</title><content type='html'>Modern OO applications use a lot of Models to present the business domain object. It is often that we have to write a matching data access object for each models, and in most cases they are just normal CRUD operations. &lt;br /&gt;&lt;br /&gt;What I am trying to do here is to create a generic way to create DAO from POJO that uses JPA as mapping tool to simplify the repeating tasks. The following example uses hibernate for DB connectivity. &lt;br /&gt;&lt;br /&gt;Of course you can simply use EJB 3.0 and remove all this completely by using method like entityManager.persist(), but if we want to stay away from EJB and persistence model, this should give you a very good place to start. (I am using JPA as my mapping tool only because of my personal preference, you can use hibernate annotation, and it should work exactly the same way).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1 - Create the Generic class&lt;/span&gt;&lt;br /&gt;I am using the sample from the "&lt;a href="http://www.ibm.com/developerworks/java/library/j-genericdao.html"&gt;Don't repeat the DAO&lt;/a&gt;". I think this is pretty neat.&lt;br /&gt;&lt;br /&gt;GenericDao Interface&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;package com.blogspot.programmingpanda.commons&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import java.util.Collection;&lt;br /&gt;&lt;br /&gt;public interface GenericDao&amp;ls;T, PK extends Serializable&amp;gt; {&lt;br /&gt;  Collection&amp;lt;T&amp;gt; listAll();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The implementation...&lt;br /&gt;GenericDaoHibernateImpl&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;package com.blogspot.programmingpanda.commons&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import java.util.Collection;&lt;br /&gt;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;&lt;br /&gt;&lt;br /&gt;public class GenericDaoHibernateImpl&amp;lt;T, PK extends Serializable&amp;gt; extends HibernateDaoSupport implements GenericDao&amp;lt;T, PK&amp;gt; {&lt;br /&gt;&lt;br /&gt;  private Class&amp;lt;T&amp;gt; type;&lt;br /&gt;&lt;br /&gt;  public GenericDaoHibernateImpl(Class&amp;lt;T&amp;gt; type){&lt;br /&gt;      this.type = type;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Collection&amp;lt;T&amp;gt; listAll() {&lt;br /&gt;      return this.getHibernateTemplate().loadAll(this.type);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * @return the type&lt;br /&gt;   */&lt;br /&gt;  public Class&amp;lt;T&amp;gt; getType() {&lt;br /&gt;      return type;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * @param type the type to set&lt;br /&gt;   */&lt;br /&gt;  public void setType(Class&amp;lt;T&amp;gt; type) {&lt;br /&gt;      this.type = type;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once we have the generic DAO class, we can use spring to inject the model into the DAO.&lt;br /&gt;&lt;br /&gt;Now we have to create the model and use JPA to do the O/R Mapping&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2 - Create the model and map it to the database&lt;/span&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;package com.blogspot.programmingpanda.commons.models;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import javax.persistence.Column;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.GenerationType;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import javax.persistence.Table;&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name="myschema.model")&lt;br /&gt;public class MyModel implements Serializable {&lt;br /&gt;&lt;br /&gt;  private Integer id;&lt;br /&gt;  private String col1;&lt;br /&gt;  private String col2;&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * @return the id&lt;br /&gt;   */&lt;br /&gt;  @Id&lt;br /&gt;  @Column(name="id")&lt;br /&gt;  @GeneratedValue(strategy = GenerationType.AUTO)&lt;br /&gt;  public Integer getId() {&lt;br /&gt;      return id;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Column(name="col1")&lt;br /&gt;  public String getCol1() {&lt;br /&gt;      return col1;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Column(name="col2")&lt;br /&gt;  public String getCol2() {&lt;br /&gt;      return col2;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /** And all those setter method **/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3 - Spring Config&lt;/span&gt;&lt;br /&gt;After the Model and GenericDao class, all we have to do is to&lt;br /&gt;i) Let the session factory know the class(es) to map&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;&amp;lt;!-- Annotation Session Factory Bean --&amp;gt;&lt;br /&gt;&amp;lt;bean id="sessionFactory"&lt;br /&gt;      class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&amp;gt;&lt;br /&gt;  &amp;lt;property name="dataSource" ref="mysqlDataSource"/&amp;gt;&lt;br /&gt;   &amp;lt;property name="hibernateProperties"&amp;gt;&lt;br /&gt;          &amp;lt;props&amp;gt;&lt;br /&gt;              &amp;lt;prop key="hibernate.dialect"&amp;gt;org.hibernate.dialect.MySQL5Dialect&amp;lt;/prop&amp;gt;&lt;br /&gt;          &amp;lt;/props&amp;gt;&lt;br /&gt;      &amp;lt;/property&amp;gt;&lt;br /&gt;  &amp;lt;property name="annotatedClasses"&amp;gt;&lt;br /&gt;    &amp;lt;list&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;value&amp;gt;com.blogspot.programmingpanda.commons.models.MyModel&amp;lt;/value&amp;gt;&lt;br /&gt;    &amp;lt;/list&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ii) Create the dao by injecting the class into the GenericDao&lt;br /&gt;&lt;pre class="brush:java"&gt;&lt;br /&gt;&amp;lt;!-- This bean will replace the actual Dao class --&amp;gt;     &lt;br /&gt;&amp;lt;bean id="myModelDao" class="com.blogspot.programmingpanda.commons.GenericDaoHibernateImpl" autowire="byName"&amp;gt;&lt;br /&gt;  &amp;lt;constructor-arg&amp;gt;&lt;br /&gt;      &amp;lt;value&amp;gt;com.blogspot.programmingpanda.commons.models.MyModel&amp;lt;/value&amp;gt;&lt;br /&gt;  &amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The full applicationContext.xml will look something like this&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;  xmlns:aop="http://www.springframework.org/schema/aop"&lt;br /&gt;  xmlns:tx="http://www.springframework.org/schema/tx"&lt;br /&gt;  xsi:schemaLocation="&lt;br /&gt;  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&lt;br /&gt;  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd&lt;br /&gt;  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;bean id="propertyConfigurer"&lt;br /&gt;     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&amp;gt;&lt;br /&gt;     &amp;lt;property name="locations"&amp;gt;&lt;br /&gt;     &amp;lt;list&amp;gt;&lt;br /&gt;              &amp;lt;value&amp;gt;/WEB-INF/spring-config/dev.properties&amp;lt;/value&amp;gt;&lt;br /&gt;  &amp;lt;/list&amp;gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;bean id="systemPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" /&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- MySql DS --&amp;gt;&lt;br /&gt;  &amp;lt;bean id="mysqlDataSource"&lt;br /&gt;      class="org.springframework.jdbc.datasource.DriverManagerDataSource"&amp;gt;&lt;br /&gt;      &amp;lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&amp;gt;&lt;br /&gt;      &amp;lt;property name="url" value="${mysql.url}" /&amp;gt;&lt;br /&gt;      &amp;lt;property name="username" value="${mysql.username}" /&amp;gt;&lt;br /&gt;      &amp;lt;property name="password" value="${mysql.password}" /&amp;gt;&lt;br /&gt;  &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- Annotation Session Factory Bean --&amp;gt;&lt;br /&gt;&amp;lt;bean id="sessionFactory"&lt;br /&gt;      class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&amp;gt;&lt;br /&gt;  &amp;lt;property name="dataSource" ref="mysqlDataSource"/&amp;gt;&lt;br /&gt;   &amp;lt;property name="hibernateProperties"&amp;gt;&lt;br /&gt;          &amp;lt;props&amp;gt;&lt;br /&gt;              &amp;lt;prop key="hibernate.dialect"&amp;gt;org.hibernate.dialect.MySQL5Dialect&amp;lt;/prop&amp;gt;&lt;br /&gt;          &amp;lt;/props&amp;gt;&lt;br /&gt;      &amp;lt;/property&amp;gt;&lt;br /&gt;  &amp;lt;property name="annotatedClasses"&amp;gt;&lt;br /&gt;    &amp;lt;list&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;value&amp;gt;com.blogspot.programmingpanda.commons.models.MyModel&amp;lt;/value&amp;gt;&lt;br /&gt;    &amp;lt;/list&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;!--sessionFactory will get autowired--&amp;gt;&lt;br /&gt;&amp;lt;bean id="hibernateInterceptor"&lt;br /&gt;      class="org.springframework.orm.hibernate3.HibernateInterceptor"&lt;br /&gt;      autowire="byName" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- This bean will replace the actual Dao class --&amp;gt;     &lt;br /&gt;&amp;lt;bean id="myModelDao" class="com.blogspot.programmingpanda.commons.GenericDaoHibernateImpl" autowire="byName"&amp;gt;&lt;br /&gt;  &amp;lt;constructor-arg&amp;gt;&lt;br /&gt;      &amp;lt;value&amp;gt;com.blogspot.programmingpanda.commons.models.MyModel&amp;lt;/value&amp;gt;&lt;br /&gt;  &amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- Inject the Dao to an action --&amp;gt;&lt;br /&gt;&amp;lt;bean id="action" class="actions.ListAction"&amp;gt;&lt;br /&gt;   &amp;lt;property name="myModelDao" ref="myModelDao" /&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;This is only a minimal example demonstrating how we can use spring, JPA annotation and a generic dao template to avoid writing DAO class for each model we create in our application. You can always extend the GenericDao class to include your own method(s) other than the generic CRUD methods.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-9196579185433128695?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/9196579185433128695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/recipe-spring-jpa-annotation-hibernate.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/9196579185433128695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/9196579185433128695'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/recipe-spring-jpa-annotation-hibernate.html' title='Recipe: Spring + JPA Annotation + Hibernate'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-4528687048302512945</id><published>2009-08-02T22:38:00.002-04:00</published><updated>2009-08-02T23:32:03.466-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pragmatic programmer'/><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Working from the list and reviewing remember the milk</title><content type='html'>i've been reading the pragamtic programmer series for the last few years now.  i've been trying to incorporate their ideas into my daily work routine whenever i get a chance.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;i was reminded of one this week when i realized my todo list at work was getting a little out of control and consisted of a piece of paper with my ugly hand writing on it.  Having a todo list is definitely the first step in getting organized, but i was not doing one thing correctly.  One of the rules (from &lt;a href="http://www.pragprog.com/titles/prj/ship-it" target="_new"&gt;Pragmatic Programmers: Ship It!&lt;/a&gt;), was that the list must be publically available and easy to update/publish.  So, here I have this massive list of things to do, and my team wasn't aware of it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;to correct this grave mistake, i signed myself up for a &lt;a href="http://rememberthemilk.com/" target="_new"&gt;Remember the Milk&lt;/a&gt; account.  It is a simple to do list manager that allows multiple lists, tagging, notes, calendar integration, rss feeds, sync-ing with smart devices (if u pay for pro) on top of the standard to do list features.  so far, i've found this quite easy to pick up.  i'm still poking around, so i'm a little slow at putting in my massive list into the system, but there are a lot of keyboard shortcuts that I'm sure will make things lightning fast when i manage to remember them.  One other cool thing is that it supports Google Gears!  the only thing that i dont like about right now is... when i add a priority to an item, it automatically updates the list to keep it sorted (the default sort is by priority).  however, i feel like i "lost" my item, b/c i dont know where it is in my list anymore.  i would much rather that I have a manual refresh button that i could click when i'm ready to re-sort the list.   &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;i guess a simple test of the product's effectiveness is if i'm still using it 4 wks later?  stay tuned to find out!!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By the way...here are the tips for maintaining a good list as per the author of "Ship it!".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Tips:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Organize whatever daily task list you do have into a formal copy of The List.&lt;/li&gt;&lt;li&gt;Prioritize your work and add rough time estimates.&lt;/li&gt;&lt;li&gt;Start working on the highest-priority item on The List. no cheating!  If some crisis forces a lower-priority item higher, record it.  You should be using your list to help you determine what you are working on next.&lt;/li&gt;&lt;li&gt;Add all new work to The List, make sure it is an accurate reflection of your current tasks.&lt;/li&gt;&lt;li&gt;Move items to your finished list as you complete tasks (this makes surviving status reports and "witch-hunts" much easier).&lt;/li&gt;&lt;li&gt;Review The List every morning (aka updated daily)&lt;/li&gt;&lt;li&gt;Make sure the list is publically available&lt;/li&gt;&lt;li&gt;Maintaining The List should not require too much effort.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Signs you are doing it wrong&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;You're too busy to update the list or it takes too long.&lt;/li&gt;&lt;li&gt;The list gets outdated because you don't update it frequently enough.&lt;/li&gt;&lt;li&gt;It takes a long time to complete one item on the list (the items are too large)&lt;/li&gt;&lt;li&gt;No one else knows about your list or there are mulitple versions&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-4528687048302512945?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/4528687048302512945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/working-from-list-and-reviewing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4528687048302512945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4528687048302512945'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/08/working-from-list-and-reviewing.html' title='Working from the list and reviewing remember the milk'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-4529383940345756791</id><published>2009-07-29T20:05:00.000-04:00</published><updated>2009-07-29T20:37:24.886-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='iis'/><title type='text'>getting an HTTP 405 on IIS</title><content type='html'>i was trying to set up this web application to connect to a HTTP server (happened to be IIS) that is serving some pre-generated report files.  The offshore developer that had been working on this had some problems getting it going, so it was left to me to deal with it.  The web application was using Apache HttpClient to connect to the http server using some standard http client code below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;&amp;lt;snip&amp;gt;&lt;br /&gt;&lt;br /&gt;HttpClient client = new HttpClient();&lt;br /&gt;&lt;br /&gt;PostMethod method = new PostMethod(filePath);&lt;br /&gt;method.setRequestHeader("Content-type", "text/html");&lt;br /&gt;client.executeMethod(method);&lt;br /&gt;input = method.getResponseBodyAsStream();&lt;br /&gt;responseBean.setInputStream(input);&lt;br /&gt;&lt;br /&gt;&amp;lt;/snip&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;that resulted in IIS throwing this at us......&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;The page cannot be displayed&lt;br /&gt;The page you are looking for cannot be displayed because an invalid method (HTTP verb) was used to attempt access.&lt;br /&gt;&lt;br /&gt;Please try the following:&lt;br /&gt;&lt;br /&gt;Contact the Web site administrator if you believe that this request should be allowed.&lt;br /&gt;Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.&lt;br /&gt;&lt;br /&gt;HTTP Error 405 - The HTTP verb used to access this page is not allowed.&lt;br /&gt;Internet Information Services (IIS)&lt;br /&gt;&lt;br /&gt;Technical Information (for support personnel)&lt;br /&gt;&lt;br /&gt;Go to &lt;a href="http://go.microsoft.com/fwlink/?linkid=8180"&gt;Microsoft Product Support Services&lt;/a&gt; and perform a title search for the words HTTP and 405.&lt;br /&gt;Open &lt;b&gt;IIS Help&lt;/b&gt;, which is accessible in IIS Manager (inetmgr),&lt;br /&gt;and search for topics titled Setting Application Mappings, &lt;b&gt;Securing Your Site with Web Site Permissions&lt;/b&gt;, and &lt;b&gt;About Custom Error Messages&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So basically what was happening was that IIS didn't like the POST method that was being used.  (HTTP 405 --&gt; Method Not Allowed).  The fix? quite simple, use a GET! =)  It is easy to forget that POST's primary objective is to post data to the server, not to obtain data from  it.  &lt;br /&gt;&lt;br /&gt;As web devs, we see HTTP 404s a lot...and the occasional 403. it's not everyday you see a 405!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-4529383940345756791?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/4529383940345756791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/getting-http-405-on-iis.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4529383940345756791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4529383940345756791'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/getting-http-405-on-iis.html' title='getting an HTTP 405 on IIS'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-2810537855301018356</id><published>2009-07-20T23:19:00.000-04:00</published><updated>2009-07-24T23:13:58.657-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='build'/><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><category scheme='http://www.blogger.com/atom/ns#' term='spring 2'/><title type='text'>Using different log4j proerties for different environment in spring 2</title><content type='html'>Default location of log4j properties is in /WEB-INF/classes/logj4.properties. There are ways to point log4j to different properties. In spring, we can do something like this.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;!-- log4j setting --&amp;gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;log4jInitialization&amp;quot;&lt;br /&gt; class=&amp;quot;org.springframework.beans.factory.config.MethodInvokingFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;targetClass&amp;quot;&lt;br /&gt;   value=&amp;quot;org.springframework.util.Log4jConfigurer&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;targetMethod&amp;quot; value=&amp;quot;initLogging&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;arguments&amp;quot;&amp;gt;&lt;br /&gt;   &amp;lt;list&amp;gt;&lt;br /&gt;    &amp;lt;value&amp;gt;log4j.properties&amp;lt;/value&amp;gt;&lt;br /&gt;   &amp;lt;/list&amp;gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;where initLogging takes (String location), you can use absolute path or relative path here. But a more elegant way is to use a variable for the application root. like this&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;value&amp;gt;${webapp.root}/${log4j.properties.location}&amp;lt;/value&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can get the ${webapp.root} from webAppRootKey. To bring it to the next level we can group all configs into 1 properties file and that will make the build process easier.&lt;br /&gt;&lt;br /&gt;The full setup looks something like this&lt;br /&gt;&lt;br /&gt;/WEB-INF/web.xml&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;listener&amp;gt;&lt;br /&gt;        &amp;lt;listener-class&amp;gt;org.springframework.web.util.WebAppRootListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;    &amp;lt;/listener&amp;gt;&lt;br /&gt;&amp;lt;listener&amp;gt;&lt;br /&gt;        &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;    &amp;lt;/listener&amp;gt;&lt;br /&gt;&amp;lt;context-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;&lt;br /&gt;            /WEB-INF/applicationContext.xml&lt;br /&gt;&amp;lt;/param-value&amp;gt;&lt;br /&gt;    &amp;lt;/context-param&amp;gt;&lt;br /&gt;    &amp;lt;context-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;webAppRootKey&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;webapp.root&amp;lt;/param-value&amp;gt;&lt;br /&gt;    &amp;lt;/context-param&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;/WEB-INF/applicationContext.xml&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;propertyConfigurer&amp;quot;&lt;br /&gt;      class=&amp;quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;locations&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;list&amp;gt;&lt;br /&gt;                &amp;lt;value&amp;gt;/WEB-INF/spring-config/dev.properties&amp;lt;/value&amp;gt;&lt;br /&gt;   &amp;lt;/list&amp;gt;&lt;br /&gt;   &amp;lt;/property&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;!-- log4j setting --&amp;gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;log4jInitialization&amp;quot;&lt;br /&gt; class=&amp;quot;org.springframework.beans.factory.config.MethodInvokingFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;targetClass&amp;quot;&lt;br /&gt;   value=&amp;quot;org.springframework.util.Log4jConfigurer&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;targetMethod&amp;quot; value=&amp;quot;initLogging&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;arguments&amp;quot;&amp;gt;&lt;br /&gt;   &amp;lt;list&amp;gt;&lt;br /&gt;    &amp;lt;value&amp;gt;${webapp.root}/${log4j.properties.location}&amp;lt;/value&amp;gt;&lt;br /&gt;   &amp;lt;/list&amp;gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;/WEB-INF/spring-config/dev.properties&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;#log4j setting&lt;br /&gt;log4j.properties.location=WEB-INF/log4j-config/log4j.dev.properties&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;/WEB-INF/log4j-config/log4j.dev.properties&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;log4j.appender.stdout=org.apache.log4j.ConsoleAppender&lt;br /&gt;log4j.appender.stdout.Target=System.out&lt;br /&gt;log4j.appender.stdout.Threshold=DEBUG&lt;br /&gt;log4j.appender.stdout.layout=org.apache.log4j.PatternLayout&lt;br /&gt;log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&lt;br /&gt;&lt;br /&gt;log4j.rootLogger=DEBUG, stdout&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;/WEB-INF/log4j-config/log4j.prod.properties&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;# Configuration for receiving e-mails when ERROR messages occur.&lt;br /&gt;log4j.appender.mail=org.apache.log4j.net.SMTPAppender&lt;br /&gt;log4j.appender.mail.To=to@mydomain.com&lt;br /&gt;log4j.appender.mail.From=from@mydomain.com&lt;br /&gt;log4j.appender.mail.SMTPHost=smtp.mydomain.com&lt;br /&gt;log4j.appender.mail.Threshold=ERROR&lt;br /&gt;log4j.appender.mail.BufferSize=1&lt;br /&gt;log4j.appender.mail.Subject=An application error occured&lt;br /&gt;log4j.appender.mail.layout=org.apache.log4j.HTMLLayout&lt;br /&gt;&lt;br /&gt;# Standrd System.out appender&lt;br /&gt;log4j.appender.stdout=org.apache.log4j.ConsoleAppender&lt;br /&gt;log4j.appender.stdout.Target=System.out&lt;br /&gt;log4j.appender.stdout.Threshold=INFO&lt;br /&gt;log4j.appender.stdout.layout=org.apache.log4j.PatternLayout&lt;br /&gt;log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&lt;br /&gt;&lt;br /&gt;log4j.rootLogger=INFO, stdout, mail&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-2810537855301018356?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/2810537855301018356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/using-different-log4j-proerties-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/2810537855301018356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/2810537855301018356'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/using-different-log4j-proerties-for.html' title='Using different log4j proerties for different environment in spring 2'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-4764256529369117242</id><published>2009-07-20T19:40:00.000-04:00</published><updated>2009-07-20T23:18:29.882-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='velocity'/><category scheme='http://www.blogger.com/atom/ns#' term='spring 2'/><title type='text'>Accessing Context/System (Application Root) properties in Spring</title><content type='html'>In the &lt;a href="http://programmingpanda.blogspot.com/2009/07/parameterize-spring-applicationcontext.html"&gt;last post&lt;/a&gt; I talked about how to parameterize the applicationContext.xml with a properties file. But sometime we would like to access system/context properties in the applicationContext.xml (for example, you want to reference a file in your webapp, but the class only takes absolute path). The spring PropertyPlaceholderConfigurer class would do the work for you as well.&lt;br /&gt;&lt;br /&gt;By default, the system property mode is set to use fall back (SYSTEM_PROPERTIES_MODE_FALLBACK), which means if a property is not in our properties file that we supply, the property will be filled with the one in the context/system.&lt;br /&gt;&lt;br /&gt;One good use would be getting the application root and use it to reference a config file.&lt;br /&gt;&lt;br /&gt;For example &lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;prop key="file.resource.loader.path"&gt;${webapp.root}/WEB-INF/velocity&lt;/prop&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(In reference to Spring documentation velocity properties &lt;a href="http://static.springsource.org/spring/docs/2.5.0/reference/view.html#view-velocity-example-velocityproperties"&gt;chapter&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;In order to use ${webapp.root} you will need to setup &lt;a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/util/WebAppRootListener.html"&gt;WebAppRootListener&lt;/a&gt; in web.xml&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;listener&gt;&lt;br /&gt;   &lt;listener-class&gt;org.springframework.web.util.WebAppRootListener&lt;/listener-class&gt;&lt;br /&gt;&lt;/listener&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and assign it to a context param&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;context-param&gt;&lt;br /&gt;   &lt;param-name&gt;webAppRootKey&lt;/param-name&gt;&lt;br /&gt;   &lt;param-value&gt;webapp.root&lt;/param-value&gt;&lt;br /&gt;&lt;/context-param&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-4764256529369117242?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/4764256529369117242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/accessing-contextsystem-application.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4764256529369117242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4764256529369117242'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/accessing-contextsystem-application.html' title='Accessing Context/System (Application Root) properties in Spring'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-8274749268985614224</id><published>2009-07-20T19:18:00.000-04:00</published><updated>2009-07-20T19:40:14.629-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring 2'/><title type='text'>Parameterize Spring applicationContext with properties file</title><content type='html'>Spring has a very useful class called &lt;a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html"&gt;PropertyPlaceholderConfigurer&lt;/a&gt; that helps you to parameterize your applicationContext.xml file. In order to use this, you will need to add the bean in spring like this&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt; &lt;bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;&lt;br /&gt;   &lt;property name="locations"&gt;&lt;br /&gt;      &lt;list&gt;&lt;br /&gt;         &lt;value&gt;/WEB-INF/spring-config/dev.properties&lt;/value&gt;&lt;br /&gt;      &lt;/list&gt;&lt;br /&gt;   &lt;/property&gt;&lt;br /&gt;&lt;/bean&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where the property &lt;span style="font-weight:bold;"&gt;location&lt;/span&gt; points to the list of properties files.&lt;br /&gt;&lt;br /&gt;I use this primarily becasue&lt;br /&gt;1. easier to maintain properties in a properties file than applicationContext&lt;br /&gt;2. switch between different environments, e.g. development vs. staging vs. production&lt;br /&gt;&lt;br /&gt;An example of the use of this would be&lt;br /&gt;&lt;br /&gt;/WEB-INF/web.xml&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;listener&gt;&lt;br /&gt;   &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;&lt;br /&gt;&lt;/listener&gt;&lt;br /&gt;    &lt;br /&gt;&lt;context-param&gt;&lt;br /&gt;   &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;&lt;br /&gt;      &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;br /&gt;   &lt;/param-value&gt;&lt;br /&gt;&lt;/context-param&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;/WEB-INF/spring-config/dev.properties&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;# Dev DB Setting&lt;br /&gt;mysql.driver=com.mysql.jdbc.Driver&lt;br /&gt;mysql.url=jdbc:mysql://dev.mydomain.com:3306/&lt;br /&gt;mysql.username=devuser&lt;br /&gt;mysql.password=xxx&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;/WEB-INF/spring-config/prod.properties&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;# Product DB Setting&lt;br /&gt;mysql.driver=com.mysql.jdbc.Driver&lt;br /&gt;mysql.url=jdbc:mysql://prod.mydomain.com:3306/&lt;br /&gt;mysql.username=produser&lt;br /&gt;mysql.password=xxx&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;/WEB-INF/applicationContext.xml&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;&lt;br /&gt;   &lt;property name="locations"&gt;&lt;br /&gt;      &lt;list&gt;&lt;br /&gt;         &lt;value&gt;/WEB-INF/spring-config/dev.properties&lt;/value&gt;&lt;br /&gt;      &lt;/list&gt;&lt;br /&gt;   &lt;/property&gt;&lt;br /&gt;&lt;/bean&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- Data Source --&gt;&lt;br /&gt;&lt;bean id="DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;&lt;br /&gt;   &lt;property name="driverClassName" value="${mysql.driver}" /&gt;&lt;br /&gt;   &lt;property name="url" value="${mysql.url}" /&gt;&lt;br /&gt;   &lt;property name="username" value="${mysql.username}" /&gt;&lt;br /&gt;   &lt;property name="password" value="${mysql.password}" /&gt;&lt;br /&gt;&lt;/bean&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To switch between environments, all you have to update is&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;value&gt;/WEB-INF/spring-config/prod.properties&lt;/value&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;in the applicationContext.xml&lt;br /&gt;&lt;br /&gt;To make it fancier, of course you can supply the properties to an ant script when you build your application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-8274749268985614224?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/8274749268985614224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/parameterize-spring-applicationcontext.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/8274749268985614224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/8274749268985614224'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/parameterize-spring-applicationcontext.html' title='Parameterize Spring applicationContext with properties file'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-6076692020637049109</id><published>2009-07-20T18:58:00.000-04:00</published><updated>2009-07-20T19:15:44.139-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><title type='text'>Setup log4j to send email when an application error occur</title><content type='html'>Apache log4j is an excellent logging facility to log application information. It is extremely easy to setup and it is very powerful. It comes with an email appender by default which you can config it to sends email when you log. &lt;br /&gt;&lt;br /&gt;Example:  Logs message to standard system.out on INFO and Sends email when an application error occurs&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;# Configuration for receiving e-mails when ERROR messages occur.&lt;br /&gt;log4j.appender.mail=org.apache.log4j.net.SMTPAppender&lt;br /&gt;log4j.appender.mail.To=to@mydomain.com&lt;br /&gt;log4j.appender.mail.From=from@mydomain.com&lt;br /&gt;log4j.appender.mail.SMTPHost=smtp.mydomain.com&lt;br /&gt;log4j.appender.mail.Threshold=ERROR&lt;br /&gt;log4j.appender.mail.BufferSize=1&lt;br /&gt;log4j.appender.mail.Subject=An application error occured&lt;br /&gt;log4j.appender.mail.layout=org.apache.log4j.HTMLLayout&lt;br /&gt;&lt;br /&gt;# Standrd System.out appender&lt;br /&gt;log4j.appender.stdout=org.apache.log4j.ConsoleAppender&lt;br /&gt;log4j.appender.stdout.Target=System.out&lt;br /&gt;log4j.appender.stdout.Threshold=INFO&lt;br /&gt;log4j.appender.stdout.layout=org.apache.log4j.PatternLayout&lt;br /&gt;log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n&lt;br /&gt;&lt;br /&gt;log4j.rootLogger=INFO, stdout, mail&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is pretty simple. The only setting that controls what to send is the Threshold property of the appender.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-6076692020637049109?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/6076692020637049109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/setup-log4j-to-send-email-when.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/6076692020637049109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/6076692020637049109'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/setup-log4j-to-send-email-when.html' title='Setup log4j to send email when an application error occur'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-6561629842782985500</id><published>2009-07-20T18:34:00.002-04:00</published><updated>2010-02-06T15:19:52.491-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='welcome-file'/><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='web.xml'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><title type='text'>Map struts .action/.do to the URL root</title><content type='html'>To map the URL root to certain welcome file, we normally just specify the welcome-file in the web.xml like this&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;welcome-file-list&gt;&lt;br /&gt;&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;&lt;br /&gt;&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;&lt;br /&gt;&lt;/welcome-file-list&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What this means is, if in a directory without specifying any file name, the web application will first look for index.html and then index.jsp.&lt;br /&gt;&lt;br /&gt;Now add struts framework into the picture, default struts extension for 1 and 2 is *.do and *.action respectively.&lt;br /&gt;&lt;br /&gt;There are 2 ways of making our application pointing to the special struts action.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;#1: Meta redirect&lt;/span&gt;&lt;br /&gt;You can keep index.html or index.jsp as welcome-file and what you need to do is put a meta refresh in these index files&lt;br /&gt;&lt;br /&gt;Struts 1&lt;br /&gt;&lt;pre class="brush:js"&gt;meta equiv="refresh" content="0;URL=/homepage.do"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Struts 2&lt;br /&gt;&lt;pre class="brush:js"&gt;meta equiv="refresh" content="0;URL=/homepage.action"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But the downside of this is - whatever action name you use would appear on the browser. (i.e. www.mydomain.com always appear as www.mydomain.com/homepage.action even user types in www.mydomain.com)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;#2: Change welcome-file and add dummy place holder file&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The second way (or better way) of fixing the struts action mapping to the URL root is to update the welcome-file list.&lt;br /&gt;&lt;br /&gt;Struts 1&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;welcome-file-list&gt;&lt;br /&gt;&lt;welcome-file&gt;homepage.do&lt;/welcome-file&gt;&lt;br /&gt;&lt;/welcome-file-list&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Struts 2&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;welcome-file-list&gt;&lt;br /&gt;&lt;welcome-file&gt;homepage.action&lt;/welcome-file&gt;&lt;br /&gt;&lt;/welcome-file-list&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And then in the WebContent Root, add a dummy file (e.g. in Struts 2 you need an empty file homepage.action)&lt;span style="color: rgb(255, 0, 0);"&gt;*This step is important, without the empty dummy file, it won't work, at least in Tomcat*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now when you hit http://www.mydomain.com your application will hit the homepage.action directly without adding the homepage.action after your url.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-6561629842782985500?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/6561629842782985500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/struts-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/6561629842782985500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/6561629842782985500'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/struts-2.html' title='Map struts .action/.do to the URL root'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-1144609695578325281</id><published>2009-07-19T23:51:00.000-04:00</published><updated>2009-07-19T23:59:32.606-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='*nix'/><category scheme='http://www.blogger.com/atom/ns#' term='video card'/><category scheme='http://www.blogger.com/atom/ns#' term='nvidia'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Nvidia Video Card on Ubuntu</title><content type='html'>I have been having problem in setting up Ubuntu on my Dell Workstation. Ubuntu documentation provide minimal help so as the forums. And I finally got this&lt;br /&gt;&lt;br /&gt;&lt;a href="http://albertomilone.com/nvidia_scripts1.html"&gt;http://albertomilone.com/nvidia_scripts1.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The script auto detects your video card and install proper driver.&lt;br /&gt;&lt;br /&gt;And of course before you run this, I recommend you to uninstall all your drivers and refresh your X.11 setting to default.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-1144609695578325281?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/1144609695578325281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/nvidia-video-card-on-ubuntu.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/1144609695578325281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/1144609695578325281'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/nvidia-video-card-on-ubuntu.html' title='Nvidia Video Card on Ubuntu'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-7943793402608638609</id><published>2009-07-19T23:14:00.000-04:00</published><updated>2009-07-19T23:50:16.644-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='ognl'/><category scheme='http://www.blogger.com/atom/ns#' term='google app engine'/><title type='text'>Struts 2 ONGL issue on Google App Engine</title><content type='html'>GAE(Google App Engine) is a very high security environment, which google limits you in everything. In order to setup your struts 2 on GAE properly, you will need to change the OgnlRuntime security manager.&lt;br /&gt;&lt;br /&gt;This is the error you will get on browser&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;HTTP ERROR: 404&lt;br /&gt;&lt;br /&gt;result 'null' not found&lt;br /&gt;RequestURI=/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And on your log&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;Jul 20, 2009 3:37:20 AM com.opensymphony.xwork2.util.logging.commons.CommonsLogger error&lt;br /&gt;SEVERE: Unable to set parameter [location] in result of type [org.apache.struts2.dispatcher.ServletDispatcherResult]&lt;br /&gt;Caught OgnlException while setting property 'location' on type 'org.apache.struts2.dispatcher.ServletDispatcherResult'. - Class: ognl.OgnlRuntime&lt;br /&gt;File: OgnlRuntime.java&lt;br /&gt;Method: invokeMethod&lt;br /&gt;Line: 508 - ognl/OgnlRuntime.java:508:-1&lt;br /&gt; at com.opensymphony.xwork2.ognl.OgnlUtil.internalSetProperty(OgnlUtil.java:392)&lt;br /&gt; at com.opensymphony.xwork2.ognl.OgnlUtil.setProperty(OgnlUtil.java:143)&lt;br /&gt; at com.opensymphony.xwork2.ognl.OgnlReflectionProvider.setProperty(OgnlReflectionProvider.java:91)&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What you have to do to fix this problem is to add a listener to set the security manager to null.&lt;br /&gt;&lt;br /&gt;Listener:&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;import javax.servlet.ServletContextEvent;&lt;br /&gt;import javax.servlet.ServletContextListener;&lt;br /&gt;import javax.servlet.http.HttpSessionAttributeListener;&lt;br /&gt;import javax.servlet.http.HttpSessionBindingEvent;&lt;br /&gt;import javax.servlet.http.HttpSessionEvent;&lt;br /&gt;import javax.servlet.http.HttpSessionListener;&lt;br /&gt;&lt;br /&gt;import ognl.OgnlRuntime;&lt;br /&gt;&lt;br /&gt;public class ONGLFixListener  implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {&lt;br /&gt;&lt;br /&gt;   public ONGLFixListener()  {&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void contextInitialized(ServletContextEvent servletContextEvent)  {&lt;br /&gt;       OgnlRuntime.setSecurityManager(null);&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   //Empty methods that do nothing for the interfaces&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;web.xml&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;listener&gt;&lt;br /&gt;  &lt;listener-class&gt;com.example.ONGLFixListener&lt;/listener-class&gt;&lt;br /&gt;&lt;/listener&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This should fix the problem. =D&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-7943793402608638609?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/7943793402608638609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/struts-2-ongl-issue-on-google-app.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/7943793402608638609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/7943793402608638609'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/struts-2-ongl-issue-on-google-app.html' title='Struts 2 ONGL issue on Google App Engine'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-8919610580592102276</id><published>2009-07-13T14:03:00.000-04:00</published><updated>2009-07-13T14:15:44.224-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Showing database size</title><content type='html'>My co-worker asked me how big is the mysql DB, I don't really know how so I did a little research and found this... &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;SELECT table_schema "Database", sum( data_length + index_length ) / 1024 / 1024 "Data Base Size in MB"&lt;br /&gt;FROM information_schema.TABLES GROUP BY table_schema ; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And it works =D&lt;br /&gt;It basically just go to the information_schema and sum up the size of the tables of each schema.&lt;br /&gt;&lt;br /&gt;The output looks something like this&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+--------------------+----------------------+&lt;br /&gt;| Database           | Data Base Size in MB |&lt;br /&gt;+--------------------+----------------------+&lt;br /&gt;| dms                |           4.51943684 | &lt;br /&gt;| hrform             |           0.06588364 | &lt;br /&gt;| information_schema |           0.00390625 | &lt;br /&gt;| mysql              |           0.42193222 | &lt;br /&gt;| ptrng              |           0.05598068 | &lt;br /&gt;| securewiki         |           1.52050400 | &lt;br /&gt;| wiki               |         584.47095490 | &lt;br /&gt;+--------------------+----------------------+&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-8919610580592102276?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/8919610580592102276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/showing-database-size.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/8919610580592102276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/8919610580592102276'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/showing-database-size.html' title='Showing database size'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-2965578890435018543</id><published>2009-07-08T23:54:00.001-04:00</published><updated>2009-07-09T00:03:36.156-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mime type'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Add mime type in tomcat to prevent IE from opening binary files instead of downloading</title><content type='html'>Not sure why tomcat doesn't have .iso and .msi mime types in web.xml. And smart Microsoft IE doesn't do a great job in file download without proper http header, it actually opens .msi and .iso and display it. In order to help IE download the binaries probably.(Note that, it works fine on Firefox and Safari). You have to explicitly add the mime type in your tomcat. To do this, simply add &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;&lt;mime-mapping&gt;&lt;br /&gt;    &lt;extension&gt;iso&lt;/extension&gt;&lt;br /&gt;    &lt;mime-type&gt;application/octet-stream&lt;/mime-type&gt;&lt;br /&gt;  &lt;/mime-mapping&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;in the $CATALINA_HOME/conf/web.xml (or your webapp's web.xml)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-2965578890435018543?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/2965578890435018543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/tomcat-mime-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/2965578890435018543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/2965578890435018543'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/tomcat-mime-type.html' title='Add mime type in tomcat to prevent IE from opening binary files instead of downloading'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-7528614399349628316</id><published>2009-07-08T23:39:00.000-04:00</published><updated>2009-07-08T23:53:15.900-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='*nix'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='shell script'/><title type='text'>Logging in shell script</title><content type='html'>We all enjoy the logging facilities in the modern programming language (e.g. log4j in java, c# logging in c#)&lt;br /&gt;&lt;br /&gt;but what about shell script? The answer is an one liner&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;LOG(){echo "$(date +%c) $*"}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;for console and &lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;LOG(){echo "$(date +%c) $*" &gt;&gt; log.txt}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;for txt out put.&lt;br /&gt;&lt;br /&gt;Of course this is not the as sophisticated as the logging framework like log4j, but it simple and easy to use.&lt;br /&gt;&lt;br /&gt;To use the function simply calls&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;LOG "Message"&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-7528614399349628316?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/7528614399349628316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/logging-in-shell-script.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/7528614399349628316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/7528614399349628316'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/logging-in-shell-script.html' title='Logging in shell script'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-1364277623938373047</id><published>2009-07-08T23:29:00.000-04:00</published><updated>2009-07-08T23:53:46.997-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><category scheme='http://www.blogger.com/atom/ns#' term='port forwarding'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='plone'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>Using apache http server as a front end of zope</title><content type='html'>There are a lot of benefit of using apache http server as a front end of an application server. One of the reason is security. Linux doesn't allow you open port under 1024 for a non root user.&lt;br /&gt;&lt;br /&gt;And in some cases it is a good idea to use apache as your front end anyway (e.g. you want to use apahce for load balancing or as a proxy server, or take advantage of a very stable http server)&lt;br /&gt;&lt;br /&gt;I personally use apache as a front end for plone+zope and tomcat. Here is a brief description on how to run apache in front of a zope+plone setup&lt;br /&gt;&lt;br /&gt;When you have your zope+plone setup, you will access the plone instance like this&lt;br /&gt;http://myhost:8000/Plone&lt;br /&gt;or in general&lt;br /&gt;http://[host]:[port]/[name_of_plone_instance]&lt;br /&gt;&lt;br /&gt;and ZMI should be running here:&lt;br /&gt;http://myhost:8000/manage&lt;br /&gt;&lt;br /&gt;In order to hide plone+zope behind apache, you will have to add this into your apache config file&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;RewriteRule ^/(.*) http://127.0.0.1:8000/VirtualHostBase/http/%{HTTP_HOST}:80/Plone/VirtualHostRoot/$1 [L,P]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where %{HTTP_HOST} is a apache variable which will be automatically filled in.&lt;br /&gt;&lt;br /&gt;The first part of the rewrite rule&lt;br /&gt;&lt;pre class="brush:js"&gt;RewriteRule ^/(.*) http://127.0.0.1:8000/&lt;/pre&gt;&lt;br /&gt;What it does is to tell apache to route all the port 80 request to localhost port 8000 which zope is running.&lt;br /&gt;&lt;br /&gt;The second part of the rewrite rule&lt;br /&gt;&lt;pre class="brush:js"&gt;VirtualHostBase/http/%{HTTP_HOST}:80/Plone/VirtualHostRoot/$1 [L,P]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;is to tell the VirtualHostMonster in zope to map all the url in the page to port 80 even it is on port 8000&lt;br /&gt;&lt;br /&gt;So now when we hit the url http://myhost/ it direct all the traffic to the underlying plone instance at port 8080.&lt;br /&gt;&lt;br /&gt;At this point, everything should work nicely. But what if we want to go to access port 8080 for the ZMI. If you have port 8080 open, you should be able to just hit it on your favorite browser. What if we do not want to poke a hole on the firewall. What you can do is to do a port forwarding over ssh.&lt;br /&gt;&lt;pre class="brush:js"&gt;&lt;br /&gt;ssh -L 9999:localhost:8080 myhost&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What it does is open a secure tunnel and forward all the traffic from the remote host to your local box.&lt;br /&gt;&lt;br /&gt;In general, you will do&lt;br /&gt;&lt;br /&gt;ssh -L [local_port]:localhost:[remote_port] [remote_host]&lt;br /&gt;&lt;br /&gt;So when you hit the URL, http://localhost:9999/manage you should be able to see the ZMI in the remote host.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-1364277623938373047?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/1364277623938373047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/using-apache-http-server-as-front-end.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/1364277623938373047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/1364277623938373047'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/using-apache-http-server-as-front-end.html' title='Using apache http server as a front end of zope'/><author><name>Drunken Programmer</name><uri>http://www.blogger.com/profile/14511740702106806225</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-827449847084420479</id><published>2009-07-08T11:09:00.000-04:00</published><updated>2009-07-08T15:19:07.713-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><category scheme='http://www.blogger.com/atom/ns#' term='port forwarding'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='plone'/><category scheme='http://www.blogger.com/atom/ns#' term='zope'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>apache in front of application server</title><content type='html'>For security reason, Linux doesn't want you to run your stuff on port 80 except apache. And in some cases it is a good idea to use apache as your front end anyway (e.g. you want to use apahce for load balancing or as a proxy server)&lt;br /&gt;&lt;br /&gt;I personally use apache as a front end for plone+zope and tomcat.&lt;br /&gt;&lt;br /&gt;When you have your zope+plone setup, you will access the plone instance like this&lt;br /&gt;http://myhost:8000/Plone&lt;br /&gt;or in general&lt;br /&gt;http://&lt;host&gt;:&lt;port&gt;/&lt;plone_instance_name&gt;&lt;br /&gt;&lt;br /&gt;and ZMI should be running here:&lt;br /&gt;http://myhost:8000/manage&lt;br /&gt;&lt;br /&gt;In order to hide plone+zope behind apache, you will have to add this into your apache config file&lt;br /&gt;&lt;br /&gt;RewriteRule ^/(.*) http://127.0.0.1:8000/VirtualHostBase/http/%{HTTP_HOST}:80/Plone/VirtualHostRoot/$1 [L,P]&lt;br /&gt;&lt;br /&gt;where %{HTTP_HOST} is a apache variable which will be automatically filled in.&lt;br /&gt;&lt;br /&gt;The first part of the rewrite rule&lt;br /&gt;&lt;code&gt;RewriteRule ^/(.*) http://127.0.0.1:8000/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;What it does is to tell apache to route all the port 80 request to localhost port 8000 which zope is running.&lt;br /&gt;&lt;br /&gt;The second part of the rewrite rule&lt;br /&gt;&lt;code&gt;VirtualHostBase/http/%{HTTP_HOST}:80/Plone/VirtualHostRoot/$1 [L,P]&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;is to tell the VirtualHostMonster in zope to map all the url in the page to port 80 even it is on port 8000&lt;br /&gt;&lt;br /&gt;So now when we hit the url http://myhost/ it direct all the traffic to the underlying plone instance at port 8080.&lt;br /&gt;&lt;br /&gt;At this point, everything should work nicely. But what if we want to go to access port 8080 for the ZMI. If you have port 8080 open, you should be able to just hit it on your favorite browser. What if we do not want to poke a hole on the firewall. What you can do is to do a port forwarding over ssh.&lt;br /&gt;&lt;br /&gt;ssh -L 9999:localhost:8090 myhost&lt;br /&gt;&lt;br /&gt;What it does is open a secure tunnel and forward all the traffic from the remote host to your local box.&lt;br /&gt;&lt;br /&gt;In general, you will do&lt;br /&gt;&lt;br /&gt;ssh -L &lt;my_local_port&gt;:localhost:&lt;remote_port&gt; &lt;remote_host_or_ip_address&gt;&lt;br /&gt;&lt;br /&gt;So when you hit the URL, http://localhost:9999/manage you should be able to see the ZMI in the remote host.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-827449847084420479?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/827449847084420479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/apache-in-front-of-application-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/827449847084420479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/827449847084420479'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/07/apache-in-front-of-application-server.html' title='apache in front of application server'/><author><name>roy</name><uri>http://www.blogger.com/profile/01700431226636892208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-4245266174628617936</id><published>2009-06-22T02:47:00.000-04:00</published><updated>2009-06-22T03:16:04.543-04:00</updated><title type='text'>showing code snippets in blogs</title><content type='html'>&lt;span style="font-size:100%;"&gt;drunken programmer has been complaining that his blog posts can't include his code properly.  So I dug out some research I did a few months ago on how to set up your blog to include code snippets.  Of course, some smart cookie has thought of how to do &lt;a href="http://alexgorbatchev.com/" target="_new"&gt;this&lt;/a&gt; already.&lt;br /&gt;&lt;br /&gt;Here's a quick step by step...&lt;br /&gt;&lt;br /&gt;1) add the syntax highlighter css and js to the &amp;lt; head&amp;gt; section of your site.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;link href="http://alexgorbatchev.com/pub/sh/2.0.278/styles/shCore.css" rel="stylesheet" type="text/css"&amp;gt;&lt;br /&gt;&amp;lt;link href="http://alexgorbatchev.com/pub/sh/2.0.278/styles/shThemeDefault.css" rel="stylesheet" type="text/css"&amp;gt;&lt;br /&gt;&amp;lt;script src="http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shCore.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src="http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushJScript.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src="http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushCSharp.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src="http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushSql.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src="http://alexgorbatchev.com/pub/sh/2.0.278/scripts/shBrushXml.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;SyntaxHighlighter.all();&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2) add the required css to the &amp;lt;head&amp;gt; section of your site&lt;br /&gt;&lt;pre class="brush: html"&gt;&lt;br /&gt;.syntaxhighlighter .line .content .block&lt;br /&gt;{&lt;br /&gt;background: none !important;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3) that's it!!!  (some ppl say that you need to set the convert line break option in blogger OFF, but mine is running ok wih it ON)&lt;br /&gt;&lt;br /&gt;4) now for actually using the syntax highlighter.  make sure that your code is surrounded by &amp;lt;pre&amp;gt; tags.  Here is an example&lt;br /&gt;&lt;pre class="brush: html"&gt;&lt;br /&gt;&amp;lt;pre class="brush:js"&amp;gt;&lt;br /&gt;alert("Hello world");&lt;br /&gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5) note that the brush type specified in this case is "js"  so that it will do syntax highlighting appropriate for javascript.  The list of all supported brush types can be found &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter:Brushes" target="_new"&gt;here&lt;/a&gt;.  Note that the brush list matches the javascript import statements you added to your &amp;lt;head&amp;gt; section in step 1.  &lt;br /&gt;&lt;br /&gt;6) finally, make sure that any content you put in between the &amp;lt;pre&amp;gt; tags are bracket escaped using something similar to &lt;a href="http://www.dan.co.jp/cases/javascript/encode_entities.html" target="_new"&gt;this&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-4245266174628617936?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/4245266174628617936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/06/showing-code-snippets-in-blogs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4245266174628617936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/4245266174628617936'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/06/showing-code-snippets-in-blogs.html' title='showing code snippets in blogs'/><author><name>programming panda</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-2210178449849189717</id><published>2009-06-10T01:35:00.001-04:00</published><updated>2009-06-10T02:31:55.217-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spring security 2.x'/><title type='text'>Add a custom Spring Security filter/handler</title><content type='html'>&lt;span style="font-family:arial;"&gt;What I am trying to do is to write a log to the database when a user logout and we are using Spring Security 2.x + CAS. So I guess the best place to implement this will be along the Spring Security filter.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://static.springsource.org/spring-security/site/docs/2.0.x/reference/ns-config.html#ns-custom-filters"&gt;&lt;span style="font-family:arial;"&gt;http://static.springsource.org/spring-security/site/docs/2.0.x/reference/ns-config.html#ns-custom-filters&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;We can replace a filter by extending org.springframework.security.ui.SpringSecurityFilter and add that into the filter chain&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;bean id="logoutFilter" class="com.mycompany.security.filter"&gt;&lt;br /&gt;&lt;sec:custom-filter position="LOGOUT_FILTER"&gt;&lt;br /&gt;&lt;/sec:custom-filter&gt;&lt;/bean&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;But instead of extending the filter a better way is to add a handler to the default logout filter. &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;blockquote&gt;    &lt;bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter"&gt;&lt;br /&gt;        &lt;sec:custom-filter position="LOGOUT_FILTER"&gt;&lt;br /&gt;        &lt;constructor-arg value="/logout"&gt;&lt;br /&gt;        &lt;constructor-arg&gt;&lt;br /&gt;            &lt;list&gt;&lt;br /&gt;                &lt;bean class="com.platform.it.commons.security.handler.LogLogoutHandler"&gt;&lt;br /&gt;                &lt;bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"&gt;&lt;br /&gt;            &lt;/list&gt;&lt;br /&gt;        &lt;/constructor-arg&gt;&lt;br /&gt;    &lt;/bean&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre  style="font-family:arial;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;public class LogLogoutHandler implements LogoutHandler{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     public void logout(HttpServletRequest arg0, HttpServletResponse arg1, Authentication arg2) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        // Log info to DB&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;span style="font-family:arial;"&gt;Sidenote:  if you are using &lt;/span&gt;sec:custom-filter, make sure you do not have any reference to the same namespace which will cause a conflict. (i.e. you cannot do sec:logout if you are using a custom logout filter)&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-2210178449849189717?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/2210178449849189717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/06/add-custom-spring-security.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/2210178449849189717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/2210178449849189717'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/06/add-custom-spring-security.html' title='Add a custom Spring Security filter/handler'/><author><name>roy</name><uri>http://www.blogger.com/profile/01700431226636892208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074672205700443198.post-5936345309424458533</id><published>2009-06-10T00:33:00.000-04:00</published><updated>2009-06-10T01:34:45.447-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='localization'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>localize database</title><content type='html'>&lt;span style="font-family:arial;"&gt;I am working on a project which I have to write a help module and it has to be l10n (coz we have Japanese and Chinese customers). And because I want the content to be editable TTW, everything has to be in the DB. Another requirement is that if the content hasn't been translated, the default content (in English will be displayed). &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The following is the DB schema (mysql dialect) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CREATE TABLE  `help_manager`.`helps` (&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `id` int(11) NOT NULL AUTO_INCREMENT,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `topic` varchar(512) NOT NULL,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `content` varchar(16384) NOT NULL,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  PRIMARY KEY (`id`)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;CREATE  TABLE IF NOT EXISTS `help_manager`.`helps_l10n` (&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `id` INT NOT NULL ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `locale_id` INT NOT NULL ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `topic` VARCHAR(512) NOT NULL ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `content` VARCHAR(16384) NULL ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  PRIMARY KEY (`id`, `locale_id`) ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  INDEX `helps_fk` (`id` ASC) ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  INDEX `locale_fk` (`locale_id` ASC) ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  CONSTRAINT `helps_fk`&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    FOREIGN KEY (`id` )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    REFERENCES `help_manager`.`helps` (`id` )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ON DELETE NO ACTION&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ON UPDATE NO ACTION,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  CONSTRAINT `locale_fk`&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    FOREIGN KEY (`locale_id` )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    REFERENCES `help_manager`.`locale` (`id` )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ON DELETE NO ACTION&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ON UPDATE NO ACTION)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ENGINE = InnoDB&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;DEFAULT CHARACTER SET = utf8&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;COLLATE = utf8_general_ci&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;CREATE  TABLE IF NOT EXISTS `help_manager`.`locale` (&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `id` INT NOT NULL AUTO_INCREMENT ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  `locale` VARCHAR(8) NULL ,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  PRIMARY KEY (`id`) )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ENGINE = InnoDB&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;So here is how you select contents from the table with a specific locale&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;SELECT COALESCE (hl.topic,h.topic) , COALESCE(hl.content, h.content) FROM helps h LEFT JOIN (helps_l10n hl, `locale` l) ON (h.id=hl.id AND l.id=hl.locale_id) AND l.locale = 'ja_JP'&lt;br /&gt;&lt;br /&gt;Side note&lt;br /&gt;mysql UTF8 encoding:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;utf8_bin: compare strings by the binary value of each character in the string&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; utf8_general_ci: compare strings using general language rules and using case-insensitive comparisons&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; utf8_general_cs: compare strings using general language rules and using case-sensitive comparisons&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;for example&lt;/span&gt;:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;Ä == A =&gt; True&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Ü == U =&gt; True&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074672205700443198-5936345309424458533?l=programmingpanda.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmingpanda.blogspot.com/feeds/5936345309424458533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmingpanda.blogspot.com/2009/06/localize-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/5936345309424458533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074672205700443198/posts/default/5936345309424458533'/><link rel='alternate' type='text/html' href='http://programmingpanda.blogspot.com/2009/06/localize-database.html' title='localize database'/><author><name>roy</name><uri>http://www.blogger.com/profile/01700431226636892208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
