当前位置 : 主页 > 网页制作 > Dojo >

使用Dojo的FilteringSelect打造具有拼音检索功能的下拉菜单(下)

来源:互联网 收集:自由互联 发布时间:2021-06-15
感谢王牌海盗的投稿!本文首发于:http://cosbor.web-144.com/?p=52 ======================================================================================= 在上一篇中,我们讲了如何利用并改造Dojo的FilteringSelec

感谢王牌海盗的投稿!本文首发于:http://cosbor.web-144.com/?p=52

=======================================================================================

在上一篇中,我们讲了如何利用并改造Dojo的FilteringSelect组件实现一个拼音检索功能的下拉菜单。本篇文章准备讲讲服务端如何为FilteringSelect更好的提供具有拼音简码的store及实现自动新增实体bean时,将相应name字段转为拼音简码后存储。服务端的例子使用了spring+hibernate。大致过程是编写一个java注解,在model实体类中标注需要进行汉字转拼音的属性字段,利用spring的AOP功能,编写一个统一切面,在dao层对保存实体的save方法进行拦截,将标注的name字段转为拼音简码后注入bean的拼音简码字段,这样使业务编码人员无需再关注对实体name字段进行拼音简码的转换工作。

首先,我们需要准备一个将汉字转换成拼音的工具类CnToSpell,可以从网上下一个叫pinyin4j的jar包,该jar包提供了一套拼音转换的API,使用其编写我们的转换工具类CnToSpell,提供一个静态方法方便的将一个汉字字符串转成拼音字符串。

? CnToSpell 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 public class CnToSpell {      /**      * 将汉字转换为全拼      *      * @param src      * @return String      */      public static String getPinYin( String src )      {          char [] t1 = null ;          t1 = src.toCharArray();          // System.out.println(t1.length);          String[] t2 = new String[t1.length];          // System.out.println(t2.length);          // 设置汉字拼音输出的格式          HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();          t3.setCaseType( HanyuPinyinCaseType.LOWERCASE );          t3.setToneType( HanyuPinyinToneType.WITHOUT_TONE );          t3.setVCharType( HanyuPinyinVCharType.WITH_V );          String t4 = "" ;          int t0 = t1.length;          try          {              for ( int i = 0 ; i < t0 ; i++ )              {                  // 判断是否为汉字字符                  // System.out.println(t1[i]);                  if ( Character.toString( t1[i] ).matches( "[\\u4E00-\\u9FA5]+" ) )                  {                      t2 = PinyinHelper.toHanyuPinyinStringArray( t1[i] , t3 ); // 将汉字的几种全拼都存到t2数组中                      t4 += t2[ 0 ]; // 取出该汉字全拼的第一种读音并连接到字符串t4后                  }                  else                  {                      // 如果不是汉字字符,直接取出字符并连接到字符串t4后                      t4 += Character.toString( t1[i] );                  }              }          }          catch ( Exception e )          {              // TODO Auto-generated catch block              e.printStackTrace();          }          return t4;      }            /**      * 提取每个汉字的首字母      * @param str      * @return String      */      public static String getPinYinHeadChar( String str )      {          HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();          t3.setCaseType( HanyuPinyinCaseType.LOWERCASE );          t3.setToneType( HanyuPinyinToneType.WITHOUT_TONE );          t3.setVCharType( HanyuPinyinVCharType.WITH_V );          String convert = "" ;          for ( int j = 0 ; j < str.length() ; j++ )          {              char word = str.charAt( j );              //提取汉字的首字母              String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray( word , t3 );              if ( pinyinArray != null )              {                  convert += pinyinArray[ 0 ].charAt( 0 );              }              else              {                  convert += word;              }          }          return convert;      }            /**      * 将字符串转换成ASCII码      * @param cnStr      * @return String      */      public static String getCnASCII( String cnStr )      {          StringBuffer strBuf = new StringBuffer();          //将字符串转换成字节序列          byte [] bGBK = cnStr.getBytes();          for ( int i = 0 ; i < bGBK.length ; i++ )          {              // System.out.println(Integer.toHexString(bGBK[i] & 0xff));              //将每个字符转换成ASCII码              strBuf.append( Integer.toHexString( bGBK[i] & 0xff ) );          }          return strBuf.toString();      }            public static void main( String[] args )      {          String cnStr = "三国人物" ;          System.out.println( getPinYin( cnStr ) );          System.out.println( getPinYinHeadChar( cnStr ) );          System.out.println( getCnASCII( cnStr ) );      } }

接下来,我们定义一个自定义注解ToPy,用来在实体bean中标注需要进行拼音转换的字段。

? ToPy 1 2 3 4 5 6 7 @Retention (RetentionPolicy.RUNTIME) @Target (ElementType.TYPE) public @interface ToPy {      String nameField();      String pyField(); }

三国人物名称的实体SanGuo

? SanGuo 01 02 03 04 05 06 07 08 09 10 11 12 @Entity @Table (name = "test_sanguo" ) @ToPy (nameField= "name" ,pyField= "py" ) //通过自定义的注解标识实体中需要进行中文名称转拼音的字段 public class SanGuo {      private Long id;      private String name;      private String py;      private String note;                 //省略seter、geter方法 }

接下来,我们编写一个spring的Advior,利用AOP技术,在保存实体前进行拦截增强,将拼音转换工作统一在切面中完成。代码如下:

? ToPyAdvior 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 @Aspect @Component public class ToPyAdvior {      //定义切点,对dao层的insert的方法调用前进行增强      @Before ( value= "execution(* com.test..*Dao.insert*(..))" )      public void doAccessCheck(JoinPoint joinPoint)      {          //取得新增实体方法insert*的参数对象          Object obj = joinPoint.getArgs()[ 0 ];          Class clazz = obj.getClass();          //通过反射获取实体上的自定义注解ToPy          ToPy as =  (ToPy)clazz.getAnnotation( ToPy. class );          Field sourceField;          Field targetField;            try            {              //根据注解中的定义获取需要转换的中文字段内容              sourceField = clazz.getDeclaredField( as.nameField() );                targetField = clazz.getDeclaredField( as.pyField() );                sourceField.setAccessible( true );                targetField.setAccessible( true );              String title = sourceField.get( obj ).toString();              //将转化后的拼音简码set到实体类的py字段              targetField.set( obj , CnToSpell.getPinYinHeadChar( title ) );            }            catch ( Exception e )            {                e.printStackTrace();            }        } }

这样一来,业务编码人员只需要在实体类中针对需要拼音转码的字段进行注解即可,而不需要在每个实体的dao层中单独处理字段拼音的编码转换工作了。

网友评论