JSF自定义组件之五 JSF实现-Renderer

46 篇文章 0 订阅
29 篇文章 0 订阅

           上篇已介绍了JSF Tag类的开发,本篇将继续介绍JSF Renderer的开发。

           Renderer类是JSF组件开发中一个较重要的类,该类主要功能是在JavaHTML之间的转换,在响应阶段将Java组件的属性转换为HTML代码,在接受请求阶段将HTML Request中传来的资料转换为Java组件的属性。

           开发Renderer类时需要集成javax.faces.render.Renderer类,需实现其中的encodedecode方法,分别用来用来转换HTML和接受HTML值。

     Render过程中,有一个难点就是如何将组件中的CSSJavascript和图片加载到客户端,这里我们会新增一个JSF Phase监听器,用来监听RESTORE_VIEW阶段,判断所请求资源是否为组件所用到的资源,如果请求资源是组件用到的CSS等资源,则直接将资源写到Response中。

 

     Renderer类代码如下:

  1. package net.moon.jsf.customer.render;
  2. import java.io.IOException;
  3. import javax.faces.FacesException;
  4. import javax.faces.component.UIComponent;
  5. import javax.faces.context.FacesContext;
  6. import javax.faces.context.ResponseWriter;
  7. import javax.faces.render.Renderer;
  8. import net.moon.jsf.customer.component.HtmlDropdownList;
  9. public class DropdownListRenderer extends Renderer {
  10.     private static final String SELECTOR = "_SELECTOR";
  11.     private static final String AREA = "_AREA";
  12.     private final static String INPUT = "_INPUT";
  13.     private final static String IMAGE = "_IMAGE";
  14.     public final static String UNIQURE_JS_KEY = "resource/moonscript.js.jsf";
  15.     public final static String UNIQURE_CSS_KEY = "resource/mooncomponent.css.jsf";
  16.     public final static String UNIQURE_IMAGE_KEY = "resource/dropdownList.png.jsf";
  17.     public final static String UNIQURE_AJAX_KEY = "moonDDL.jsf";
  18.     @Override
  19.     public void decode(FacesContext context, UIComponent component) {
  20.         // TODO Auto-generated method stub
  21.         super.decode(context, component);
  22.     }
  23.     private void renderResourceOnce(FacesContext context) throws IOException {
  24.         // render javascript to client
  25.         Object isRendered = context.getExternalContext().getRequestMap().get(
  26.                 UNIQURE_JS_KEY);
  27.         ResponseWriter out = context.getResponseWriter();
  28.         out.write("/n");
  29.         if (isRendered != null && (Boolean) isRendered) {
  30.         } else {
  31.             // rendered the javascript
  32.             out.startElement("script"null);
  33.             out.writeAttribute("type""text/javascript"null);
  34.             out.writeAttribute("src", UNIQURE_JS_KEY, null);
  35.             out.endElement("script");
  36.             context.getExternalContext().getRequestMap().put(UNIQURE_JS_KEY,
  37.                     true);
  38.         }
  39.         out.write("/n");
  40.         isRendered = context.getExternalContext().getRequestMap().get(
  41.                 UNIQURE_CSS_KEY);
  42.         if (isRendered != null && (Boolean) isRendered) {
  43.         } else {
  44.             // rendered this css
  45.             out.startElement("link"null);
  46.             out.writeAttribute("rel""stylesheet"null);
  47.             out.writeAttribute("type""text/css"null);
  48.             out.writeAttribute("href", UNIQURE_CSS_KEY, null);
  49.             out.endElement("link");
  50.             out.write("/n");
  51.             context.getExternalContext().getRequestMap().put(UNIQURE_CSS_KEY,
  52.                     true);
  53.         }
  54.     }
  55.     @Override
  56.     public void encodeBegin(FacesContext context, UIComponent component)
  57.             throws IOException {
  58.         // TODO Auto-generated method stub
  59.         super.encodeBegin(context, component);
  60.         renderResourceOnce(context);
  61.         if (context == null || component == null) {
  62.             throw new FacesException("context can't be null");
  63.         }
  64.         if (!(component instanceof HtmlDropdownList)) {
  65.             throw new FacesException("error dropdownList object");
  66.         }
  67.         rendererInput(context, (HtmlDropdownList) component);
  68.         rendererImage(context, (HtmlDropdownList) component);
  69.         rendererOthers(context, (HtmlDropdownList) component);
  70.     }
  71.     private void rendererOthers(FacesContext context, HtmlDropdownList component)
  72.             throws IOException {
  73.         String clientId = component.getClientId(context);
  74.         ResponseWriter out = context.getResponseWriter();
  75.         out.startElement("div", component);
  76.         out.writeAttribute("id", clientId + AREA, null);
  77.         out.writeAttribute("class""dropdown_area"null);
  78.         out.startElement("select", component);
  79.         out.writeAttribute("id", clientId + SELECTOR, null);
  80.         out.writeAttribute("name", clientId + SELECTOR, null);
  81.         out.writeAttribute("multiple""multiple"null);
  82.         out.writeAttribute("class""dropdown_selector"null);
  83.         out.writeAttribute("onchange""giveValue();"null);
  84.         out.endElement("select");
  85.         out.endElement("div");
  86.     }
  87.     private void rendererImage(FacesContext context, HtmlDropdownList component)
  88.             throws IOException {
  89.         // TODO Auto-generated method stub
  90.         String clientId = component.getClientId(context);
  91.         ResponseWriter out = context.getResponseWriter();
  92.         String imageURL = component.getImage();
  93.         out.startElement("image", component);
  94.         out.writeAttribute("src", imageURL == null ? UNIQURE_IMAGE_KEY
  95.                 : imageURL, null);
  96.         out.writeAttribute("id", clientId + IMAGE, null);
  97.         out.writeAttribute("name", clientId + IMAGE, null);
  98.         out.writeAttribute("class""dropdown_button"null);
  99.         out.writeAttribute("onclick""showSelector(this, '"
  100.                 + (component.getValueList() == null ? component
  101.                         .getValueExpression("valueList").getExpressionString()
  102.                         : component.getValueList()) + "');"null);
  103.         out.endElement("image");
  104.     }
  105.     public DropdownListRenderer() {
  106.         super();
  107.         // TODO Auto-generated constructor stub
  108.     }
  109.     private void rendererInput(FacesContext context, HtmlDropdownList component)
  110.             throws IOException {
  111.         String clientId = component.getClientId(context);
  112.         String root = context.getExternalContext().getRequestContextPath();
  113.         ResponseWriter out = context.getResponseWriter();
  114.         out.startElement("input", component);
  115.         out.writeAttribute("type""text"null);
  116.         out.writeAttribute("id", clientId + INPUT, null);
  117.         out.writeAttribute("name", clientId + INPUT, null);
  118.         out.writeAttribute("class",
  119.                 component.getStyleClass() == null ? "dropdown_input"
  120.                         : component.getStyleClass(), null);
  121.         String changeMethod = component.getValueChange();
  122.         if (changeMethod != null) {
  123.             out.writeAttribute("onchange""callBack('" + root + "/"
  124.                     + UNIQURE_AJAX_KEY + "?ACTION=VALUECHANGE', '"
  125.                     + changeMethod + "', '');"null);
  126.         }
  127.         out.endElement("input");
  128.     }
  129. }

Phase Listener代码如下:

 

  1. package net.moon.jsf.customer.listener;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.io.OutputStreamWriter;
  7. import java.io.PrintWriter;
  8. import java.net.URL;
  9. import java.net.URLConnection;
  10. import javax.el.ValueExpression;
  11. import javax.faces.event.PhaseEvent;
  12. import javax.faces.event.PhaseId;
  13. import javax.faces.event.PhaseListener;
  14. import javax.servlet.ServletOutputStream;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;
  17. import net.moon.jsf.customer.render.DropdownListRenderer;
  18. public class DropDownListener implements PhaseListener {
  19.     public void afterPhase(PhaseEvent event) {
  20.         // TODO Auto-generated method stub
  21.         String rootId = event.getFacesContext().getViewRoot().getViewId();
  22.         String root = "/";
  23.         if (rootId.endsWith(DropdownListRenderer.UNIQURE_JS_KEY.replace(".jsf",
  24.                 ".jsp"))) {
  25.             handleResourceRequest(event, root
  26.                     + DropdownListRenderer.UNIQURE_JS_KEY, "text/javascript");
  27.         } else if (rootId.endsWith(DropdownListRenderer.UNIQURE_CSS_KEY
  28.                 .replace(".jsf"".jsp"))) {
  29.             handleResourceRequest(event, root
  30.                     + DropdownListRenderer.UNIQURE_CSS_KEY, "text/javascript");
  31.         } else if (rootId.endsWith(DropdownListRenderer.UNIQURE_IMAGE_KEY
  32.                 .replace(".jsf"".jsp"))) {
  33.             handleImageRequest(event, root
  34.                     + DropdownListRenderer.UNIQURE_IMAGE_KEY, "image/png");
  35.         } else if (rootId
  36.                 .endsWith(root
  37.                         + DropdownListRenderer.UNIQURE_AJAX_KEY.replace(".jsf",
  38.                                 ".jsp"))) {
  39.             handleAjaxEvent(event);
  40.         }
  41.     }
  42.     private void handleAjaxEvent(PhaseEvent event) {
  43.         HttpServletResponse response = (HttpServletResponse) event
  44.                 .getFacesContext().getExternalContext().getResponse();
  45.         PrintWriter out = null;
  46.         Object req = event.getFacesContext().getExternalContext().getRequest();
  47.         HttpServletRequest request = null;
  48.         if (!(req instanceof HttpServletRequest)) {
  49.             return;
  50.         }
  51.         request = (HttpServletRequest) req;
  52.         String action = request.getParameter("ACTION");
  53.         try {
  54.             out = response.getWriter();
  55.             ValueExpression ve = event.getFacesContext().getApplication()
  56.                     .getExpressionFactory().createValueExpression(
  57.                             event.getFacesContext().getELContext(), action,
  58.                             String.class);
  59.             if (!ve.isLiteralText()) {
  60.                 out.write((String) ve.getValue(event.getFacesContext()
  61.                         .getELContext()));
  62.             } else {
  63.                 out.write(ve.toString());
  64.             }
  65.             response.setStatus(HttpServletResponse.SC_OK);
  66.             event.getFacesContext().responseComplete();
  67.         } catch (IOException ex) {
  68.             ex.printStackTrace();
  69.         }
  70.         
  71.     }
  72.     private void handleImageRequest(PhaseEvent event, String resource,
  73.             String contentType) {
  74.         resource = resource.replace(".jsf""");
  75.         URL url = this.getClass().getResource(resource);
  76.         HttpServletResponse response = (HttpServletResponse) event
  77.                 .getFacesContext().getExternalContext().getResponse();
  78.         ServletOutputStream out = null;
  79.         response.setContentType(contentType);
  80.         response.setStatus(200);
  81.         InputStream input = null;
  82.         try {
  83.             input = url.openStream();
  84.             out = response.getOutputStream();
  85.             byte[] cache = new byte[1024];
  86.             int readed = 0;
  87.             while ((readed = input.read(cache)) != -1) {
  88.                 try {
  89.                     out.write(cache, 0, readed);
  90.                 } catch (Exception ex) {
  91.                     System.out.println("*****");
  92.                     ex.printStackTrace();
  93.                 }
  94.             }
  95.             input.close();
  96.             out.flush();
  97.             out.close();
  98.         } catch (IOException e) {
  99.             // TODO Auto-generated catch block
  100.             e.printStackTrace();
  101.         }
  102.         event.getFacesContext().responseComplete();
  103.     }
  104.     private void handleResourceRequest(PhaseEvent event, String resource,
  105.             String contentType) {
  106.         resource = resource.replace(".jsf""");
  107.         URL url = DropDownListener.class.getResource(resource);
  108.         URLConnection conn = null;
  109.         InputStream stream = null;
  110.         BufferedReader bufReader = null;
  111.         HttpServletResponse response = (HttpServletResponse) event
  112.                 .getFacesContext().getExternalContext().getResponse();
  113.         OutputStreamWriter outWriter = null;
  114.         String curLine = null;
  115.         try {
  116.             outWriter = new OutputStreamWriter(response.getOutputStream(),
  117.                     response.getCharacterEncoding());
  118.             conn = url.openConnection();
  119.             conn.setUseCaches(false);
  120.             stream = conn.getInputStream();
  121.             bufReader = new BufferedReader(new InputStreamReader(stream));
  122.             response.setContentType(contentType);
  123.             response.setStatus(200);
  124.             while (null != (curLine = bufReader.readLine())) {
  125.                 outWriter.write(curLine + "/n");
  126.             }
  127.             outWriter.flush();
  128.             outWriter.close();
  129.             event.getFacesContext().responseComplete();
  130.         } catch (Exception e) {
  131.             String message = "Can't load resource:" + url.toExternalForm();
  132.             System.err.println(message);
  133.             e.printStackTrace();
  134.         }
  135.     }
  136.     public void beforePhase(PhaseEvent event) {
  137.         // TODO Auto-generated method stub
  138.     }
  139.     public PhaseId getPhaseId() {
  140.         // TODO Auto-generated method stub
  141.         return PhaseId.RESTORE_VIEW;
  142.     }
  143. }

    本篇就介绍这些,下篇将对组件进行总体汇总,并提供完整代码下载。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值