首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

构建支持AJAX的JSF组件(2)

2012-11-04 
构建支持AJAX的JSF组件(二)2.AJAX处理服务器组件这个组件接受来自浏览器的AJAX请求,返回响应。AJAX服务器组

构建支持AJAX的JSF组件(二)
2.AJAX处理服务器组件
这个组件接受来自浏览器的AJAX请求,返回响应。AJAX服务器组件可以实现成
a.完全独立的HTTP服务器对象,例如通过servlet.
b.集成到JSF应用程序的AJAX服务对象。例如组件的decode()方法货PhaseListener充当AJAX服务器组件。
对于使用decode()方法充当服务器组件还要再讨论下。
虽然对于decode()的拦截方法有如下定义:“对于请求的一个非常重要的要求是:表单名称也必须做为参数传递给JSF应用程序。如果没有传递这个值,JSF应用程序会吧请求解释为 none-post-back请求,所以不会进入decode()方法。所以生成的response是非AJAX的完整HTML页面。可以用一下JavaScript代码把formName 和 ajaxreq参数组合在一起。
var formdata = "formName=" + window.document.forms[0].id + "&ajaxreq=true";”
但本人查阅了部分资料发现decode()方法现在已经不能拦截AJAX post-back请求了。但即使把表单名称(window.docuent.forms[0].id)传递进去也不会被JSF应用程序当作post-back请求而进入decode()方法。官方推荐方法是使用PhaseListener充当AJAX服务器组件。
接下来给出PhaseListener的实现DataProviderPhListener.java 。在这段代码离不仅拦截了AJAX post-back请求而且还渲染了上段gridajax.js代码到页面内。
请注意

public PhaseId getPhaseId() {        return PhaseId.ANY_PHASE;    }
由于每次阶段变化都执行它,所以返回ANY_PHASE。在beforePhase中只接受生命周期的第六个阶段所以使用PhaseId.RENDER_RESPONSE,而在在afterPhase中只接受生命周期的第一个阶段所以使用PhaseId.RESTORE_VIEW
DataProviderPhListener.java
package phaselistener;import java.io.BufferedReader;import java.util.Map;import javax.faces.context.FacesContext;import javax.faces.event.PhaseEvent;import javax.faces.event.PhaseId;import javax.faces.event.PhaseListener;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.URL;import java.net.URLConnection;import javax.faces.FactoryFinder;import javax.faces.context.ResponseWriter;import javax.faces.el.EvaluationException;import javax.faces.render.RenderKit;import javax.faces.render.RenderKitFactory;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import util.JSONGenerator;/** * * @author love */public class DataProviderPhListener implements PhaseListener {    public static final String RENDER_SCRIPT_VIEW_ID = "SpellCheckTextArea.ajaxScript";    private static final String SCRIPT_RESOURCE_NAME = "/com/jsfcompref/components/component/gridajax.js";    public PhaseId getPhaseId() {        return PhaseId.ANY_PHASE;    }    /**     * <p>Go through each component in the AJAX_VALIDATOR_COMPONENTS     * list in request scope.     */    public void afterPhase(PhaseEvent event) {        // If this is restoreView phase and the viewId is the script view id        if(event.getPhaseId() == PhaseId.RESTORE_VIEW){            if (-1 != event.getFacesContext().getViewRoot().getViewId().indexOf(RENDER_SCRIPT_VIEW_ID) &&                    PhaseId.RESTORE_VIEW == event.getPhaseId()) {                // render the script                writeScript(event);                event.getFacesContext().responseComplete();            }        }    }    public void beforePhase(PhaseEvent event) {        if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {            FacesContext context = event.getFacesContext();            Map requestMap = context.getExternalContext().getRequestParameterMap();                        if (requestMap.containsKey("ajaxreq")) {                HttpServletResponse response =                    (HttpServletResponse) context.getExternalContext().getResponse();                HttpServletRequest request =                    (HttpServletRequest) context.getExternalContext().getRequest();                response.setContentType("text/xml");                response.setHeader("Cache-Control", "no-cache");                try {                    ResponseWriter writer = FacesContext.getCurrentInstance().getResponseWriter();                    if (null == writer) {                        RenderKitFactory rkf = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);                        RenderKit renderKit = rkf.getRenderKit(context, context.getViewRoot().getRenderKitId());                        writer = renderKit.createResponseWriter(response.getWriter(), "text/html", request.getCharacterEncoding());                        context.setResponseWriter(writer);                    }                    JSONGenerator jsonGen = new JSONGenerator(request.getParameter("input"), context);                    String jsonOut = jsonGen.getJsonResponse();                    writer.write(jsonOut);                    context.responseComplete();//             return;                } catch (EvaluationException ee) {                    ee.printStackTrace();                } catch (IOException ioe) {                    ioe.printStackTrace();                }            }        }    }    private void writeScript(PhaseEvent event) {        URL url = getClass().getResource(SCRIPT_RESOURCE_NAME);        URLConnection conn = null;        InputStream stream = null;        BufferedReader bufReader = null;        HttpServletResponse response = (HttpServletResponse) event.getFacesContext().getExternalContext().getResponse();        OutputStreamWriter outWriter = null;        String curLine = null;        response.setCharacterEncoding("GBK");        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("text/javascript;charset=UTF-8");            response.setStatus(200);            while (null != (curLine = bufReader.readLine())) {                outWriter.write(curLine + "\n");            }            outWriter.flush();            outWriter.close();        } catch (Exception e) {            String message = null;            message = "Can't load script file:" +                    url.toExternalForm();            try {                response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);            } catch (IOException f) {                f.printStackTrace();            }        }    }}

这里使用了一个助手类JSONGenerator用于将查询数据库得到的结果转化成dojo.Grid可以接受的JSON格式这里的数据库查询操作使用了NetBean提供的DataProvider。感觉很像.NET的数据绑定技术。
JSONGenerator.java
package util;import com.sun.data.provider.impl.CachedRowSetDataProvider;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Date;import javax.faces.application.FacesMessage;import javax.faces.context.FacesContext;import javax.faces.el.ValueBinding;import javax.sql.rowset.CachedRowSet;import org.json.JSONArray;import org.json.JSONObject;import webapplication3.SessionBean1;/** * * @author love */public class JSONGenerator {    private String jsonResponse;    private CachedRowSetDataProvider personDataProvider = new CachedRowSetDataProvider();    public CachedRowSetDataProvider getPersonDataProvider() {        return personDataProvider;    }    public void setPersonDataProvider(CachedRowSetDataProvider crsdp) {        this.personDataProvider = crsdp;    }    public JSONGenerator(String input,FacesContext context){        ValueBinding vb = context.getApplication().createValueBinding("#{SessionBean1.personRowSet}");        personDataProvider.setCachedRowSet((CachedRowSet) vb.getValue(context));//        SessionBean1  sessionb = (SessionBean1)context.getApplication().getVariableResolver().resolveVariable(context, "SessionBean1");        SessionBean1  sessiona = (SessionBean1)context.getApplication().getELResolver().getValue(context.getELContext(), null, "SessionBean1");//        SessionBean1 sessionb = (SessionBean1) JSFUtil.getManagedObject("#{SessionBean1}",SessionBean1.class);        try {            sessiona.getPersonRowSet().setObject(1, input.toUpperCase()+"%");            personDataProvider.refresh();            CachedRowSet cache = personDataProvider.getCachedRowSet();            cache.execute();            ResultSet rs = cache.getOriginal();             JSONArray list = new JSONArray();            try {                while (rs.next()) {                    JSONObject jsobj = new JSONObject();                    String id = rs.getString("PERSONID");                    String name = rs.getString("NAME");                    String job = rs.getString("JOBTITLE");                    String fre = rs.getString("FREQUENTFLYER");                    Date date = rs.getDate("LASTUPDATED");                    jsobj.put("LASTUPDATED", date==null?"":date);                    jsobj.put("FREQUENTFLYER", !fre.isEmpty()?fre:"");                    jsobj.put("JOBTITLE", !job.isEmpty()?job:"");                    jsobj.put("NAME", !name.isEmpty()?name:"");                    jsobj.put("PERSONID", !id.isEmpty()?id:"");                    list.put(jsobj);                }                String jsonText = list.toString();                jsonText = jsonText.replace('"', '\'');                jsonResponse = "{" + String.format("identifier: 'PERSONID', label: 'NAME', items: %1$s", jsonText) + "}";            } catch (SQLException ex) {                context.addMessage(null,              new FacesMessage(FacesMessage.SEVERITY_ERROR, "Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID"), null));            }        }catch (Exception e) {e.printStackTrace();}    }    /**     * @return the jsonResponse     */    public String getJsonResponse() {        return jsonResponse;    }    /**     * @param jsonResponse the jsonResponse to set     */    public void setJsonResponse(String jsonResponse) {        this.jsonResponse = jsonResponse;    }}

热点排行