{"id":30,"date":"2007-08-14T21:49:43","date_gmt":"2007-08-14T21:49:43","guid":{"rendered":"http:\/\/euve3303.vserver.de\/stefan\/blog\/?p=32"},"modified":"2011-12-02T21:21:03","modified_gmt":"2011-12-02T20:21:03","slug":"jsf-components-mit-spring-und-velocity-templates","status":"publish","type":"post","link":"https:\/\/cogito-ergo-blog.de\/blog\/2007\/08\/14\/jsf-components-mit-spring-und-velocity-templates\/","title":{"rendered":"JSF Components mit Spring und Velocity-Templates"},"content":{"rendered":"<h3>JSF Spring Integration<\/h3>\n<p>\nDie Integration von JSF und Spring ist mit Spring 2.0 und den neuen Beanscopes schon recht einfach geworden. Was aber immer noch nicht so ohne weiteres geht, ist das Erzeugen von Componenten mit Spring.\n<\/p>\n<p>Angeregt von <a href=\"http:\/\/www.jroller.com\/RickHigh\/\">Rick Hightower&#8217;s Sleepless Night in Tucson<\/a> bzw. seinen Ver\u00f6ffentlichungen auf <a href=\"http:\/\/www.thearcmind.com\/confluence\/display\/SpribernateSF\/Home\">ArcMind<\/a> habe ich etwas Code zusammengestellt, der Componenten mit Hilfe von Spring instanziiert und zum Rendern einfach eine Template-Engine wie <a href=\"http:\/\/velocity.apache.org\/\">Velocity<\/a> oder <a href=\"http:\/\/freemarker.sourceforge.net\/\">Freemarker<\/a> benutzt.\n<\/p>\n<p>\nMit Spring lassen sich diese Komponenten dann einfach konfigurieren und f\u00fcr sehr einfache Sachen ist man mit dem Schreiben der Templates schon fertig.\n<\/p>\n<p><!--more--><\/p>\n<h3>Facelets machen das Leben leichter<\/h3>\n<p>\nWenn man zus\u00e4tzlich noch <a href=\"https:\/\/facelets.dev.java.net\/\">Facelets<\/a> nutzt, dann kann man sich auch das Scheiben eines JSP-Tags ersparen, eine einfache XML-Datei (Facelets Taglib) reicht schon, um die neue Komponente verwenden zu k\u00f6nnen.\n<\/p>\n<p>\nWill man nun ein neues Tag verwenden, dann sieht eine solche Taglib z.B. so aus:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;!DOCTYPE facelet-taglib PUBLIC\r\n  &quot;-\/\/Sun Microsystems, Inc.\/\/DTD Facelet Taglib 1.0\/\/EN&quot;\r\n  &quot;http:\/\/java.sun.com\/dtd\/facelet-taglib_1_0.dtd&quot;&gt; \r\n&lt;facelet-taglib&gt; \r\n\t&lt;namespace&gt; http:\/\/www.stefan-rinke.de\/facelets\/test&lt;\/namespace&gt; \r\n\t&lt;tag&gt; \r\n\t\t&lt;tag-name&gt; foo&lt;\/tag-name&gt; \r\n\t\t&lt;component&gt; \r\n\t\t\t&lt;component-type&gt;templateComponent&lt;\/component-type&gt; \r\n\t\t&lt;\/component&gt; \r\n\t&lt;\/tag&gt; \r\n&lt;\/facelet-taglib&gt; \r\n<\/pre>\n<\/p>\n<h3>Spring zum Erzeugen der Componente<\/h3>\n<p>\nWenn nun Spring zum Einsatz kommt bei der Erzeugung der Komponente, dann wird z.B. folgender ApplicationContext definiert:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;?xml version=&quot;1.0&quot;?&gt; \r\n&lt;beans xmlns=&quot;http:\/\/www.springframework.org\/schema\/beans&quot;\r\n\t     xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot;\r\n\t     xmlns:aop=&quot;http:\/\/www.springframework.org\/schema\/aop&quot;\r\n\t     xsi:schemaLocation=&quot;http:\/\/www.springframework.org\/schema\/beans\r\n              http:\/\/www.springframework.org\/schema\/beans\/spring-beans-2.0.xsd\r\n              http:\/\/www.springframework.org\/schema\/aop \r\n              http:\/\/www.springframework.org\/schema\/aop\/spring-aop-2.0.xsd&quot;&gt; \r\n\r\n\t&lt;bean id=&quot;templateEngine&quot; class=&quot;com.rinke.solutions.template.velocity.VelocityTemplateEngine&quot; init-method=&quot;init&quot;&gt; \r\n\t\t&lt;property name=&quot;properties&quot;&gt; \r\n\t\t\t&lt;props&gt; \r\n\t\t\t\t&lt;prop key=&quot;resource.loader&quot;&gt; class&lt;\/prop&gt; \r\n\t\t\t\t&lt;prop key=&quot;class.resource.loader.class&quot;&gt; org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader&lt;\/prop&gt; \r\n\t\t\t&lt;\/props&gt; \r\n\t\t&lt;\/property&gt; \r\n\t&lt;\/bean&gt; \r\n\t&lt;bean id=&quot;templateComponent&quot; class=&quot;com.rinke.solutions.jsf.TemplateComponent&quot;&gt; \r\n\t\t&lt;property name=&quot;family&quot; value=&quot;com.rinke.solutions.jsf.TemplateComponent&quot;\/&gt; \r\n\t\t&lt;property name=&quot;templateEngine&quot; ref=&quot;templateEngine&quot;\/&gt; \r\n\t\t&lt;property name=&quot;beginTemplateName&quot; value=&quot;vm\/test-begin.vm&quot;\/&gt; \r\n\t\t&lt;property name=&quot;endTemplateName&quot; value=&quot;vm\/test-end.vm&quot;\/&gt; \r\n\t&lt;\/bean&gt; \r\n&lt;\/beans&gt; \r\n<\/pre>\n<\/p>\n<p>\nDas ist schon alles (ausser den Templates zum Rendern) was man f\u00fcr eine einfache neue Komponente braucht, der Rest ist etwas Infrastruktur:<\/p>\n<ul>\n<li>SpringApplicationFactory und SpringApplication zum Erzeugen von Components via Spring.<\/li>\n<li>Eine Abstraktion f\u00fcr TemplateEngines wie Velocity oder Freemarker in Form von 2 Interfaces.<\/li>\n<li>Eine Basis-Klasse TemplateComponent, die f\u00fcr einfache &#8220;Ausgabe&#8221;-Components bereits alles hat, ansonsten eben entsprechend zu Erweitern ist.<\/li>\n<\/ul>\n<p>\nDie Basis-Klasse f\u00fcr Template-Components sieht so aus:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n    package com.rinke.solutions.jsf;\r\n\r\n    import java.io.IOException;\r\n\r\n    import javax.faces.component.UIComponentBase;\r\n    import javax.faces.context.FacesContext;\r\n\r\n    import com.rinke.solutions.template.Template;\r\n    import com.rinke.solutions.template.TemplateContext;\r\n    import com.rinke.solutions.template.TemplateEngine;\r\n    \/**\r\n    * simple base class for components rendered by templates\r\n    * @author sr\r\n    *\/\r\n    public class TemplateComponent extends UIComponentBase {\r\n\r\n      private String family;\r\n      private TemplateEngine templateEngine;\r\n      private Template beginTemplate;\r\n      private Template endTemplate;\r\n      private String beginTemplateName;\r\n      private String endTemplateName;\r\n     \r\n      @Override\r\n      public String getFamily() {\r\n        return family;\r\n      }\r\n\r\n      \/**\r\n       * set family via spring ;-)\r\n       * @param family\r\n       *\/\r\n      public void setFamily(String family) {\r\n        this.family = family;\r\n      }\r\n\r\n      @Override\r\n      public void encodeBegin(FacesContext context) throws IOException {\r\n        TemplateContext tc = templateEngine.createTemplateContext();\r\n        populateContext(tc,context);\r\n        getBeginTemplate().process(tc,context.getResponseWriter());\r\n      }\r\n\r\n      \/**\r\n       * populates the template context with some common objects.\r\n       * @param context the TemplateContext\r\n       * @param ctx the current faces context\r\n       *\/\r\n      private void populateContext(TemplateContext context, FacesContext ctx) {\r\n        context.put(&quot;component&quot;, this);\r\n        context.put(&quot;context&quot;, ctx);\r\n        context.put(&quot;session&quot;, ctx.getExternalContext().getSessionMap());\r\n        context.put(&quot;param&quot;, ctx.getExternalContext().getRequestParameterMap());\r\n        context.put(&quot;facesContext&quot;, ctx);\r\n      }\r\n\r\n      @Override\r\n      public void encodeEnd(FacesContext context) throws IOException {\r\n        TemplateContext tc = templateEngine.createTemplateContext();\r\n        populateContext(tc,context);\r\n        getEndTemplate().process(tc,context.getResponseWriter());\r\n      }\r\n\r\n      public Template getBeginTemplate() {\r\n        if (beginTemplate == null) {\r\n          beginTemplate = templateEngine.loadTemplate(beginTemplateName);\r\n        }\r\n        return beginTemplate;\r\n      }\r\n\r\n      public Template getEndTemplate() {\r\n        if (endTemplate == null) {\r\n          endTemplate = templateEngine.loadTemplate(endTemplateName);\r\n        }\r\n        return endTemplate;\r\n      }\r\n\r\n      public String getBeginTemplateName() {\r\n        return beginTemplateName;\r\n      }\r\n\r\n      public void setBeginTemplateName(String beginTemplateName) {\r\n        this.beginTemplateName = beginTemplateName;\r\n      }\r\n\r\n      public String getEndTemplateName() {\r\n        return endTemplateName;\r\n      }\r\n\r\n      public void setEndTemplateName(String endTemplateName) {\r\n        this.endTemplateName = endTemplateName;\r\n      }\r\n\r\n      public void setTemplateEngine(TemplateEngine templateEngine) {\r\n        this.templateEngine = templateEngine;\r\n      }\r\n\r\n    } \r\n\r\n<\/pre><\/p>\n","protected":false},"excerpt":{"rendered":"<p>JSF Spring Integration Die Integration von JSF und Spring ist mit Spring 2.0 und den neuen Beanscopes schon recht einfach geworden. Was aber immer noch nicht so ohne weiteres geht, ist das Erzeugen von Componenten mit Spring. Angeregt von Rick &hellip; <a href=\"https:\/\/cogito-ergo-blog.de\/blog\/2007\/08\/14\/jsf-components-mit-spring-und-velocity-templates\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/30"}],"collection":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=30"}],"version-history":[{"count":2,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/30\/revisions"}],"predecessor-version":[{"id":10042,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/30\/revisions\/10042"}],"wp:attachment":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=30"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=30"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=30"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}