java整合discuz小结(实现与论坛同步登陆等操做)

        最近笔者在实现java项目对discuz的整合。在此过程当中,查了不少这方面的资料,发现网上并无说得比较全面的文章。笔者博取众长以及本身在此过程当中遇到的问题,写下来供你们参考,但愿你们能够在这过程当中少走弯路。笔者在此过程当中主要参考了https://code.google.com/p/discuz-ucenter-api-for-java/后,感谢做者ping china.你们能够到此下载接口。 php

        第一步:写好你的配置文件config.properties。      java

        UC_API = http://你的discuz地址/uc_server  如http://localhost/forum/uc_server
        UC_IP = 正常状况下留空便可
        UC_KEY = 123456(与ucenter通讯的密钥,这里本身设定,需与discuz ucenter一支)
        UC_APPID = 2
        UC_CONNECT = 正常状况下留空便可
web

        第二步:在你的web.xml里加上         api

<!-- servlet 'disuz_uc_api' 用于接收Discuz UCenter的同步消息, 此项配置必须有。(可适当调整 load-on-startup参数) -->
        <servlet>
            <servlet-name>disuz_uc_api</servlet-name>
            <servlet-class>com.fivestars.interfaces.bbs.api.UC</servlet-class>
            <load-on-startup>2</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>disuz_uc_api</servlet-name>
            <url-pattern>/api/uc.php</url-pattern>
        </servlet-mapping>

         

        第三步:配置ucenter. 浏览器

        以管理员身份登陆-》管理中心-》ucenter-》应用管理。 安全

        填写如下信息:应用名称:你的应用的名称 app

        通讯密钥:你刚在config.properties的UC_KEY (123456) 测试

        是否开启同步登陆:是 ui

        是否接受通知:是 google

        其余的留空便可。

        而后咱们先试一下登陆,如下是测试代码。(到这里还不支持中文,后面会提到)

        

public static String login(String userName,String pwd){ 
       Client e = new Client();
       String result = e.uc_user_login(userName, pwd);
       String $ucsynlogin = "";
 
       LinkedList<String> rs = XMLHelper.uc_unserialize(result);
       if(rs.size()>0){
            int $uid = Integer.parseInt(rs.get(0));
            String $username = rs.get(1);
            String $password = rs.get(2);
            String $email = rs.get(3);
            if($uid > 0) {
                $ucsynlogin = e.uc_user_synlogin($uid); 
            } else if($uid == -1) {
                System.out.println("用户不存在,或者被删除");
            } else if($uid == -2) {
                System.out.println("密码错");
            } else {
                System.out.println("未定义");
            }
        }else{
            System.out.println("Login failed");
            System.out.println(result);
        }
        return $ucsynlogin;
    }

    建一个测试类,把这个方法加进去,而后调用此方法,传参数值用户名和密码,而后返回的是一个string。string的内容是一段js代码。只要把这段js代码输出到页面上去就实现了discuz那边的登陆了。你能够先试试把这段js输入到浏览器的地址栏。

    退出测试代码:

      

        public static String logout(){
            Client uc = new Client();
            String $ucsynlogout = uc.uc_user_synlogout();
            System.out.println("退出成功"+$ucsynlogout);
            return $ucsynlogout;
        }

    此方法也是返回一段js。输出页面便可,测试时能够先在浏览器地址栏输入。

    注册测试代码:

     

public static void reg(String userName, String password, String email) {
       Client uc = new Client();
       String $returns = uc.uc_user_register(userName, password ,email);
       int $uid = Integer.parseInt($returns);
       if($uid <= 0) {
            if($uid == -1) {
                System.out.print("用户名不合法");
            } else if($uid == -2) {
                System.out.print("包含要容许注册的词语");
            } else if($uid == -3) {
                System.out.print("用户名已经存在");
            } else if($uid == -4) {
                System.out.print("Email 格式有误");
            } else if($uid == -5) {
                System.out.print("Email 不容许注册");
            } else if($uid == -6) {
                System.out.print("该 Email 已经被注册");
            } else {
                System.out.print("未定义");
            }
        } else {
            System.out.println("OK:------------------------"+$returns);
        }
    }

到这里,还只是实现了java项目登陆后论坛那边能自动登陆,但论坛那边登陆了,java这边还没登陆。别急,咱们先解决一下中文用户名的问题,其实这个问题https://code.google.com/p/discuz-ucenter-api-for-java/里已经提到了,并提供了解决方案。感谢原做者。但我仍是啰嗦一下,由于我感受说的不够详细,你们可能要花去你的宝贵时间去了解。解决方法以下:

        在PHPFuctions.java里有一个名叫urlencode的方法。

        只要用如下方法重载一下就好        

    protected String urlencode(String value,String code){
            try {
                return URLEncoder.encode(value,code);
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
                return null;
        }

        并把Client.java里的uc_api_input方法改为以下     

public String uc_api_input(String $data) {
 String $s = urlencode(uc_authcode($data+"&agent="+md5("")+"&time="+time(), "ENCODE"            , UC_KEY),"GBK");
     return $s;
}

        好!java中文登陆问题解决了。咱们来看看discuz那边登陆了,java这边怎么实现同步登陆。在uc.java里有一个doanswer的方法。全部同步操做都在这个方法里完成。其逻辑是这样的,uc这个类继承了HttpServlet。当ucenter发出通知时,会访问这个servlet.并执行他的doGet()方法。doGet()调用doAnswer().

        String $code = request.getParameter("code");会传一个code进来(加密了的)。而后调用$code = new Client().uc_authcode($code, "DECODE");进行解密操做。新建一个Map,Map<String,String> $get = new HashMap<String, String>();而后根据解密出来的code的内容封装这个Map.调用这个方法,parse_str($code, $get); 通过以上操做后,全部同步操做须要的信息都在map里,如action。action表明的是什么操做,如同步登陆,同步退出,修改密码等。还有其余信息,如username.登陆的用户名。改密码时还会传新密码过来。全部的这些都包含在这个叫$get的Map里。而后咱们就能够进行咱们本身的逻辑操做了。(以上逻辑不想理解不要紧,你只要知道当你在discuz登陆以后,uc.java的doAnswer()方法就会被调用,你所须要的一切信息都包含在$get这个Map里)

        操做到这里,你必定想吐槽笔者!不行啊,discuz那边登陆了,java这边彻底没反应啊!!doAnswer方法没有被调用啊!是的,你还须要到discuz后台作一些设置。管理中心->站长->ucenter设置。把ucenter链接方式改成接口方式。而后,你登陆discuz时,doAnswer()方法就会被调用了。(其余操做如退出也同样)

        到这里,咱们又遇到了中文的问题了,discuz用中文登陆的时候不行啊!是的,这确实是个比较麻烦的问题。笔者也弄了很久。缘由是这样的,上面提到过,传进来的$code是须要uc_authcode()方法进行解密的,当中文的时候解密出来的$code是"".解决方法以下:在Client.java的uc_authcode()方法里找到这句String $result = $result1.substring(0, $result1.length());并把它改为:        

String $result= $result1.toString();  
        try{  
           $result=new String($result.getBytes("iso-8859-1"),"GBK");
         }catch (Exception e) {  
            $result = $result1.substring(0, $result1.length());  
            // TODO: handle exception  
         }

这样还不行,解密出来的code中文部分还是乱码。因此在uc.java的$code = new Client().uc_authcode($code, "DECODE");这句下面还要加上$code = new String($code.getBytes("GBK"),"UTF-8");可能有人会说直接转成utf-8不行吗?为何要先转成gbk呢?若是直接转成utf-8的话,解密出来的$code是""。到此中文的问题就获得解决了。笔者下载的是GBK版本的discuz,其余状况本身改一下编码应该没问题。

        至此,只要咱们在doAnswer()方法里添加咱们本身的逻辑代码就已经能实现java和discuz的同步了。另外,有个问题提醒你们,就是在discuz那边修改密码的时候,ucenter并非立刻发出通知的,这可能会引发同步和安全的问题。

        可能有地方写漏了!!若有相关问题须要了解可留言  

相关文章
相关标签/搜索