FCKeditor与JSF的整合

FCKeditor,作为现在功能最强大的在线HTML编辑器,网上关于他的功能介绍以及基本配置已经很多了。然而其中不少文章涉及面都比较局限。最近,笔者需要在自己项目中使用到FCKeditor,并用之于和已有的基于JSF的web应用整合。从对FCKeditor一窍不通到成功达成整合,我从网上学到了不少知识,自己也积累了不少经验,因此,也想和大家一起分析这一过程。

   1.基本配置:

      知之为知之,不知google之。关于FCKeditor的基本配置在网上自有高人指点,这里我也不多耽误大家时间。主要是谈下自己当初配置的问题:
    a.基本路径:
        注意FCKeditor的基本路径应该是/(你的web应用名称)/(放置FCKeditor文件的文件夹名)/
        我的目录结构为:
        r_str.jpg
        因此,我的基本路径设置为:/fck/FCKeditor/

     b.文件浏览以及上传路径设置:
        我个人的参考如下:
      
None.gif FCKConfig.LinkBrowser = true ;
None.gifFCKConfig.LinkBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Connector=connectors/jsp/connector' ;
None.gifFCKConfig.LinkBrowserWindowWidth    = FCKConfig.ScreenWidth * 0.7 ;        // 70%
None.gifFCKConfig.LinkBrowserWindowHeight    = FCKConfig.ScreenHeight * 0.7 ;    // 70%
None.gif
None.gifFCKConfig.ImageBrowser = true ;
None.gifFCKConfig.ImageBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Image
&Connector =connectors/jsp/connector';
None.gifFCKConfig.ImageBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;    // 70% ;
None.gifFCKConfig.ImageBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;    // 70% ;
None.gif
None.gifFCKConfig.FlashBrowser = true ;
None.gifFCKConfig.FlashBrowserURL = FCKConfig.BasePath + 'filemanager/browser/default/browser.html?Type=Flash
&Connector =connectors/jsp/connector' ;
None.gifFCKConfig.FlashBrowserWindowWidth  = FCKConfig.ScreenWidth * 0.7 ;    //70% ;
None.gifFCKConfig.FlashBrowserWindowHeight = FCKConfig.ScreenHeight * 0.7 ;    //70% ;
None.gif
None.gifFCKConfig.LinkUpload = true ;
None.gifFCKConfig.LinkUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=File' ;
None.gifFCKConfig.LinkUploadAllowedExtensions    = "" ;            // empty for all
None.gifFCKConfig.LinkUploadDeniedExtensions    = ".(php|php3|php5|phtml|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|dll|reg|cgi)$" ;    // empty for no one
None.gif
None.gifFCKConfig.ImageUpload = true ;
None.gifFCKConfig.ImageUploadURL =FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Image' ;
None.gifFCKConfig.ImageUploadAllowedExtensions    = ".(jpg|gif|jpeg|png)$" ;        // empty for all
None.gifFCKConfig.ImageUploadDeniedExtensions    = "" ;                            // empty for no one
None.gif
None.gifFCKConfig.FlashUpload = true ;
None.gifFCKConfig.FlashUploadURL = FCKConfig.BasePath + 'filemanager/upload/simpleuploader?Type=Flash' ;
None.gifFCKConfig.FlashUploadAllowedExtensions    = ".(swf|fla)$" ;        // empty for all
None.gifFCKConfig.FlashUploadDeniedExtensions    = "" ;                    // empty for no one


2.与JSF整合。

  FCKeditor与JSF整合的最大问题,在于需要从JSF环境中相应Bean读取值赋予给FCKeditor,同时从FCKeditor里面读取结果赋予给相应的数据持有Bean。由于这一过程在传统的JSF标签中是通过值绑定有框架自动完成,因此这里需要我们手动来实现这一过程。
  以下要展示的demo由两部分组成:
   form.jsp显示编辑内容,点击其submit按钮跳转至test.jsp,test.jsp调用FCKeditor对form.jsp中显示的已有内容进行显示和编辑。编辑完后点击submit,页面将重新跳转到form.jsp,显示修改后的内容。
  其实,这就是一个很基本的编辑功能,在论坛和blog中都可以看到它的身影。
   而ContextBean用于持有待编辑的内容,它的scope是session范围。ContextServlet用于读取FCKeditor修改后的内容,并赋予ContextBean中。

    首先来看form.jsp
None.gif < body >   
None.gif        
< f:view >
None.gif            
< h:form >
None.gif                
< pre >
None.gif                
< h:outputText  value ="#{td.name}"  escape ="false" ></ h:outputText >
None.gif                
</ pre >
None.gif                                
< br />
None.gif                
< h:commandButton  value ="submit"  action ="#{td.submit}" ></ h:commandButton >
None.gif            
</ h:form >
None.gif        
</ f:view >
None.gif    
</ body >

    这个页面很简单,其中td对应的就是ContextBean,ContextBean.name用于保存编辑内容

None.gif package  com.dyerac;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   class  ContextBean  dot.gif {
InBlock.gif    
private String name;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public String getName() dot.gif{
InBlock.gif        
return name;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public void setName(String name) dot.gif{
InBlock.gif        
this.name = name;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public String submit() dot.gif{
InBlock.gif        
InBlock.gif        
return "edit";
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}


下面来看test.jsp
 用过FCKeditor的都知道,FCKeditor可以通过三种方式来调用:
 script, jsp 标签以及java代码。
这里,为了方便从ContextBean中读取name属性内容作为其初始值,我使用了第三种方法
其中 FCKeditor fck = new  FCKeditor(request, " EditorDefault " );初始化FCKeditor,第二个参数即为该FCKeditor实例的id,当提交后FCKeditor内的内容将以该参数为变量名保存在request中。
比如,这里我选择了 EditorDefault,所以日后读取FCKeditor内容时,可以通过以下语句:
request.getParameter("EditorDefault")

None.gif < body >
None.gif        
< form action = " /fck/servlet/ContextServlet "  method = " post "  target = " _blank " >
None.gif        
<% FCKeditor fck = new  FCKeditor(request, " EditorDefault " );
None.gif          FacesContext fcg
= FacesContext.getCurrentInstance();
None.gif          ContextBean td
= (ContextBean)fcg.getApplication().getVariableResolver().resolveVariable(fcg, " td " );
None.gif          fck.setBasePath(
" /fck/FCKeditor/ " );
None.gif          fck.setValue(td.getName());
None.gif          fck.setHeight(
new  Integer( 600 ).toString());
None.gif          out.print(fck.create());
None.gif         
%>
None.gif         
< input type = " submit "  value = " Submit " >
None.gif    
</ body >

 修改后的结果以post方式提交给/fck/servlet/ContextServlet,该url对应的即为ContextServlet。
ContextServlet负责读取FCKeditor里的内容,并赋予给session中的ContextBean。doPost()方法用于实现该功能

None.gif public   void  doPost(HttpServletRequest request, HttpServletResponse response)
ExpandedBlockStart.gifContractedBlock.gif            
throws  ServletException, IOException  dot.gif {
InBlock.gif        FacesContext fcg 
= getFacesContext(request,response);
InBlock.gif        ContextBean td 
= (ContextBean) fcg.getApplication()
InBlock.gif                .getVariableResolver().resolveVariable(fcg, 
"td");
InBlock.gif        String name
=new String(request.getParameter("EditorDefault").getBytes("ISO-8859-1"),"UTF-8");
InBlock.gif        td.setName(name);
InBlock.gif        RequestDispatcher rd
=getServletContext().getRequestDispatcher("/form.faces");
InBlock.gif        rd.forward(request, response);
ExpandedBlockEnd.gif    }

需要注意两个问题,
其一:FCKeditor内的中文信息读取是可能出现乱码,需要额外的处理:
   String name=new String(request.getParameter("EditorDefault").getBytes("ISO-8859-1"),"UTF-8");
其二:由于servlet处于FacesContext范围外,因此不能通过FacesContext.getCurrentInstance()来得到当前FacesContext,因此ContextServlet定义了自己的方法用于获取FacesContext:

None.gif //      You need an inner class to be able to call FacesContext.setCurrentInstance
None.gif
//      since it's a protected method
None.gif
     private   abstract   static   class  InnerFacesContext  extends  FacesContext
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif      
protected static void setFacesContextAsCurrentInstance(FacesContext facesContext) dot.gif{
InBlock.gif        FacesContext.setCurrentInstance(facesContext);
ExpandedSubBlockEnd.gif      }

ExpandedBlockEnd.gif    }

None.gif
ExpandedBlockStart.gifContractedBlock.gif    
private  FacesContext getFacesContext(ServletRequest request, ServletResponse response)  dot.gif {
InBlock.gif      
// Try to get it first
InBlock.gif
      FacesContext facesContext = FacesContext.getCurrentInstance();
InBlock.gif      
if (facesContext != nullreturn facesContext;
InBlock.gif
InBlock.gif      FacesContextFactory contextFactory 
= (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
InBlock.gif      LifecycleFactory lifecycleFactory 
= (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
InBlock.gif      Lifecycle lifecycle 
= lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
InBlock.gif
InBlock.gif      
// Either set a private member servletContext = filterConfig.getServletContext();
InBlock.gif      
// in you filter init() method or set it here like this:
InBlock.gif      
// ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
InBlock.gif      
// Note that the above line would fail if you are using any other protocol than http
InBlock.gif
      ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
InBlock.gif
InBlock.gif      
// Doesn't set this instance as the current instance of FacesContext.getCurrentInstance
InBlock.gif
      facesContext = contextFactory.getFacesContext(servletContext, request, response, lifecycle);
InBlock.gif
InBlock.gif      
// Set using our inner class
InBlock.gif
      InnerFacesContext.setFacesContextAsCurrentInstance(facesContext);
InBlock.gif
InBlock.gif      
// set a new viewRoot, otherwise context.getViewRoot returns null
InBlock.gif      
//UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "yourOwnID");
InBlock.gif      
//facesContext.setViewRoot(view);
InBlock.gif

InBlock.gif      
return facesContext;
ExpandedBlockEnd.gif    }
 

   ContextServlet处理完了FCKeditor内容后,将跳转到form.jsp。
这样一个简单的编辑功能就完成了。

3.遗留问题:

   我在上传文件时还是会出现中文乱码的问题,按照其他人说的那样把网页的charset=utf-8改成gb2312一样会有问题,还请各位高手赐教^_^


另外,关于整个demo的源代码如果大家需要,可以留言给我,我用邮箱发给您。不足之处,还请各位多多指点

内容概要:本文详细介绍了基于FPGA的144输出通道可切换电压源系统的设计实现,涵盖系统总体架构、FPGA硬件设计、上位机软件设计以及系统集成方案。系统由上位机控制软件(PC端)、FPGA控制核心和高压输出模块(144通道)三部分组成。FPGA硬件设计部分详细描述了Verilog代码实现,包括PWM生成模块、UART通信模块和温度监控模块。硬件设计说明中提及了FPGA选型、PWM生成方式、通信接口、高压输出模块和保护电路的设计要点。上位机软件采用Python编写,实现了设备连接、命令发送、序列控制等功能,并提供了一个图形用户界面(GUI)用于方便的操作和配置。 适合人群:具备一定硬件设计和编程基础的电子工程师、FPGA开发者及科研人员。 使用场景及目标:①适用于需要精确控制多通道电压输出的实验环境或工业应用场景;②帮助用户理解和掌握FPGA在复杂控制系统中的应用,包括PWM控制、UART通信及多通道信号处理;③为研究人员提供一个可扩展的平台,用于测试和验证不同的电压源控制算法和策略。 阅读建议:由于涉及硬件和软件两方面的内容,建议读者先熟悉FPGA基础知识和Verilog语言,同时具备一定的Python编程经验。在阅读过程中,应结合硬件电路图和代码注释,逐步理解系统的各个组成部分及其相互关系。此外,实际动手搭建和调试该系统将有助于加深对整个设计的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值