您的位置:首页 > Web前端 > JavaScript

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

2008-09-01 11:46 549 查看
           上篇已介绍了JSF Tag类的开发,本篇将继续介绍JSF Renderer的开发。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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

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

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

 

     Renderer类代码如下:

package net.moon.jsf.customer.render;

import java.io.IOException;

import javax.faces.FacesException;

import javax.faces.component.UIComponent;

import javax.faces.context.FacesContext;

import javax.faces.context.ResponseWriter;

import javax.faces.render.Renderer;

import net.moon.jsf.customer.component.HtmlDropdownList;

public class DropdownListRenderer extends Renderer {

    private static final String SELECTOR = "_SELECTOR";

    private static final String AREA = "_AREA";

    private final static String INPUT = "_INPUT";

    private final static String IMAGE = "_IMAGE";

    public final static String UNIQURE_JS_KEY = "resource/moonscript.js.jsf";

    public final static String UNIQURE_CSS_KEY = "resource/mooncomponent.css.jsf";

    public final static String UNIQURE_IMAGE_KEY = "resource/dropdownList.png.jsf";

    public final static String UNIQURE_AJAX_KEY = "moonDDL.jsf";

    @Override

    public void decode(FacesContext context, UIComponent component) {

        // TODO Auto-generated method stub

        super.decode(context, component);

    }

    private void renderResourceOnce(FacesContext context) throws IOException {

        // render javascript to client

        Object isRendered = context.getExternalContext().getRequestMap().get(

                UNIQURE_JS_KEY);

        ResponseWriter out = context.getResponseWriter();

        out.write("/n");

        if (isRendered != null && (Boolean) isRendered) {

        } else {

            // rendered the javascript

            out.startElement("script", null);

            out.writeAttribute("type", "text/javascript", null);

            out.writeAttribute("src", UNIQURE_JS_KEY, null);

            out.endElement("script");

            context.getExternalContext().getRequestMap().put(UNIQURE_JS_KEY,

                    true);

        }

        out.write("/n");

        isRendered = context.getExternalContext().getRequestMap().get(

                UNIQURE_CSS_KEY);

        if (isRendered != null && (Boolean) isRendered) {

        } else {

            // rendered this css

            out.startElement("link", null);

            out.writeAttribute("rel", "stylesheet", null);

            out.writeAttribute("type", "text/css", null);

            out.writeAttribute("href", UNIQURE_CSS_KEY, null);

            out.endElement("link");

            out.write("/n");

            context.getExternalContext().getRequestMap().put(UNIQURE_CSS_KEY,

                    true);

        }

    }

    @Override

    public void encodeBegin(FacesContext context, UIComponent component)

            throws IOException {

        // TODO Auto-generated method stub

        super.encodeBegin(context, component);

        renderResourceOnce(context);

        if (context == null || component == null) {

            throw new FacesException("context can't be null");

        }

        if (!(component instanceof HtmlDropdownList)) {

            throw new FacesException("error dropdownList object");

        }

        rendererInput(context, (HtmlDropdownList) component);

        rendererImage(context, (HtmlDropdownList) component);

        rendererOthers(context, (HtmlDropdownList) component);

    }

    private void rendererOthers(FacesContext context, HtmlDropdownList component)

            throws IOException {

        String clientId = component.getClientId(context);

        ResponseWriter out = context.getResponseWriter();

        out.startElement("div", component);

        out.writeAttribute("id", clientId + AREA, null);

        out.writeAttribute("class", "dropdown_area", null);

        out.startElement("select", component);

        out.writeAttribute("id", clientId + SELECTOR, null);

        out.writeAttribute("name", clientId + SELECTOR, null);

        out.writeAttribute("multiple", "multiple", null);

        out.writeAttribute("class", "dropdown_selector", null);

        out.writeAttribute("onchange", "giveValue();", null);

        out.endElement("select");

        out.endElement("div");

    }

    private void rendererImage(FacesContext context, HtmlDropdownList component)

            throws IOException {

        // TODO Auto-generated method stub

        String clientId = component.getClientId(context);

        ResponseWriter out = context.getResponseWriter();

        String imageURL = component.getImage();

        out.startElement("image", component);

        out.writeAttribute("src", imageURL == null ? UNIQURE_IMAGE_KEY

                : imageURL, null);

        out.writeAttribute("id", clientId + IMAGE, null);

        out.writeAttribute("name", clientId + IMAGE, null);

        out.writeAttribute("class", "dropdown_button", null);

        out.writeAttribute("onclick", "showSelector(this, '"

                + (component.getValueList() == null ? component

                        .getValueExpression("valueList").getExpressionString()

                        : component.getValueList()) + "');", null);

        out.endElement("image");

    }

    public DropdownListRenderer() {

        super();

        // TODO Auto-generated constructor stub

    }

    private void rendererInput(FacesContext context, HtmlDropdownList component)

            throws IOException {

        String clientId = component.getClientId(context);

        String root = context.getExternalContext().getRequestContextPath();

        ResponseWriter out = context.getResponseWriter();

        out.startElement("input", component);

        out.writeAttribute("type", "text", null);

        out.writeAttribute("id", clientId + INPUT, null);

        out.writeAttribute("name", clientId + INPUT, null);

        out.writeAttribute("class",

                component.getStyleClass() == null ? "dropdown_input"

                        : component.getStyleClass(), null);

        String changeMethod = component.getValueChange();

        if (changeMethod != null) {

            out.writeAttribute("onchange", "callBack('" + root + "/"

                    + UNIQURE_AJAX_KEY + "?ACTION=VALUECHANGE', '"

                    + changeMethod + "', '');", null);

        }

        out.endElement("input");

    }

}

Phase Listener代码如下:

 

package net.moon.jsf.customer.listener;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.URL;

import java.net.URLConnection;

import javax.el.ValueExpression;

import javax.faces.event.PhaseEvent;

import javax.faces.event.PhaseId;

import javax.faces.event.PhaseListener;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import net.moon.jsf.customer.render.DropdownListRenderer;

public class DropDownListener implements PhaseListener {

    public void afterPhase(PhaseEvent event) {

        // TODO Auto-generated method stub

        String rootId = event.getFacesContext().getViewRoot().getViewId();

        String root = "/";

        if (rootId.endsWith(DropdownListRenderer.UNIQURE_JS_KEY.replace(".jsf",

                ".jsp"))) {

            handleResourceRequest(event, root

                    + DropdownListRenderer.UNIQURE_JS_KEY, "text/javascript");

        } else if (rootId.endsWith(DropdownListRenderer.UNIQURE_CSS_KEY

                .replace(".jsf", ".jsp"))) {

            handleResourceRequest(event, root

                    + DropdownListRenderer.UNIQURE_CSS_KEY, "text/javascript");

        } else if (rootId.endsWith(DropdownListRenderer.UNIQURE_IMAGE_KEY

                .replace(".jsf", ".jsp"))) {

            handleImageRequest(event, root

                    + DropdownListRenderer.UNIQURE_IMAGE_KEY, "image/png");

        } else if (rootId

                .endsWith(root

                        + DropdownListRenderer.UNIQURE_AJAX_KEY.replace(".jsf",

                                ".jsp"))) {

            handleAjaxEvent(event);

        }

    }

    private void handleAjaxEvent(PhaseEvent event) {

        HttpServletResponse response = (HttpServletResponse) event

                .getFacesContext().getExternalContext().getResponse();

        PrintWriter out = null;

        Object req = event.getFacesContext().getExternalContext().getRequest();

        HttpServletRequest request = null;

        if (!(req instanceof HttpServletRequest)) {

            return;

        }

        request = (HttpServletRequest) req;

        String action = request.getParameter("ACTION");

        try {

            out = response.getWriter();

            ValueExpression ve = event.getFacesContext().getApplication()

                    .getExpressionFactory().createValueExpression(

                            event.getFacesContext().getELContext(), action,

                            String.class);

            if (!ve.isLiteralText()) {

                out.write((String) ve.getValue(event.getFacesContext()

                        .getELContext()));

            } else {

                out.write(ve.toString());

            }

            response.setStatus(HttpServletResponse.SC_OK);

            event.getFacesContext().responseComplete();

        } catch (IOException ex) {

            ex.printStackTrace();

        }

        

    }

    private void handleImageRequest(PhaseEvent event, String resource,

            String contentType) {

        resource = resource.replace(".jsf", "");

        URL url = this.getClass().getResource(resource);

        HttpServletResponse response = (HttpServletResponse) event

                .getFacesContext().getExternalContext().getResponse();

        ServletOutputStream out = null;

        response.setContentType(contentType);

        response.setStatus(200);

        InputStream input = null;

        try {

            input = url.openStream();

            out = response.getOutputStream();

            byte[] cache = new byte[1024];

            int readed = 0;

            while ((readed = input.read(cache)) != -1) {

                try {

                    out.write(cache, 0, readed);

                } catch (Exception ex) {

                    System.out.println("*****");

                    ex.printStackTrace();

                }

            }

            input.close();

            out.flush();

            out.close();

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        event.getFacesContext().responseComplete();

    }

    private void handleResourceRequest(PhaseEvent event, String resource,

            String contentType) {

        resource = resource.replace(".jsf", "");

        URL url = DropDownListener.class.getResource(resource);

        URLConnection conn = null;

        InputStream stream = null;

        BufferedReader bufReader = null;

        HttpServletResponse response = (HttpServletResponse) event

                .getFacesContext().getExternalContext().getResponse();

        OutputStreamWriter outWriter = null;

        String curLine = null;

        try {

            outWriter = new OutputStreamWriter(response.getOutputStream(),

                    response.getCharacterEncoding());

            conn = url.openConnection();

            conn.setUseCaches(false);

            stream = conn.getInputStream();

            bufReader = new BufferedReader(new InputStreamReader(stream));

            response.setContentType(contentType);

            response.setStatus(200);

            while (null != (curLine = bufReader.readLine())) {

                outWriter.write(curLine + "/n");

            }

            outWriter.flush();

            outWriter.close();

            event.getFacesContext().responseComplete();

        } catch (Exception e) {

            String message = "Can't load resource:" + url.toExternalForm();

            System.err.println(message);

            e.printStackTrace();

        }

    }

    public void beforePhase(PhaseEvent event) {

        // TODO Auto-generated method stub

    }

    public PhaseId getPhaseId() {

        // TODO Auto-generated method stub

        return PhaseId.RESTORE_VIEW;

    }

}

    本篇就介绍这些,下篇将对组件进行总体汇总,并提供完整代码下载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jsf null dropdown image input css