没错。就是用Ucenter。
.在叙述的过程中,我很多不必要的步骤会忽略,所以看这篇文章前需要的基础:
1.会基本使用discuz。
2.有最基本相关的java web基础。
3.有基本的php基础。
一。准备工作:
1.首先去安装discuz x2.5。去官方网下载最新版。
2.安装的时候选discuzx2.5 带UCenter版,因为带UCenter 不用自己另外安装UCenter,如果自己安装UCenter的话,到时候同步登录的时候,发觉同步的不是同一账户。(至于怎样安装,自己百度)
3. 下载java与UCenter的借口包:http://code.google.com/p/discuz-ucenter-api-for-java。这个包很强大,感觉提供这个包的作者。
二、java与Ucenter通信
1.进入到UCenter后台,添加应用。
安装方式:自定义
应用类型:其他
应用名称:JAVA项目名称,可随意
应用主URL:JAVA项目的访问地址,例如:http://localhost:8080/XXX
通信密钥:任意字符,例如:123456
应用接口文件名称:uc.php,这个不要改,前面也不要加/api/,UCenter在与其通信时会自动转换为:http://localhost:8080/javaTest/api/uc.php
是否开启同步登录:是
是否接受通知:是
以上的配置项必填,其他保持为空即可。
点击“提交”,保存成功后,记下该JAVA应用的APPID,下面的配置中会需要。
此时返回应用列表,UCenter会自动进行通信验证,不出意外肯定会出现“通信失败”的字样,先不必管它。
2.java端的配置
2-1、从“discuz-ucenter-api-for-java”的开源项目网站中下载相关的API文件
2-2、将JAVA_UCenter.zip解压、覆盖到你的JAVA项目中,其中的新文件有:
src/config.properties:本地的JAVA项目与UCenter的接口配置文件(需要根据实际环境进行配置)
src/api/ucenter/Base64.java
src/api/ucenter/Client.java:将常用的UCenter操作封装成的客户端对象,我们在项目中主要用它来与UCenter打交道
src/api/ucenter/PHPFunctions.java
src/api/ucenter/UC.java:本地的JAVA项目用来接收UCenter同步命令的Servlet接口,其访问地址必须为:/api/uc.php
src/api/ucenter/XMLHelper.java
WebRoot/WEB-INF/web.xml:主要就是将src/api/ucenter/UC.java定义为Servlet
(1) src/config.properties中的代码如下:
# ================================================
# Ucenter API for JAVA
# ================================================
UC_API = http://localhost
UC_IP =
UC_KEY = 123456
UC_APPID = 2
UC_CONNECT =
其中,UC_API表示UCenter的访问地址,UC_KEY就是在UCenter中添加新应用时定义的通信密钥,UC_APPID表示新应用的APPID,就是刚才记下的那个。
除这三项外,其他的配置保持为空即可。
(2) WebRoot/WEB-INF/web.xml中的代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<display-name>同步UC Server发出的操作指令</display-name>
<servlet-name>UC</servlet-name>
<servlet-class>api.ucenter.UC</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>UC</servlet-name>
<url-pattern>/api/uc.php</url-pattern>
</servlet-mapping>
</web-app>
别的无所谓,只需注意这一行:<url-pattern>/api/uc.php</url-pattern>
2-3、JAVA端配置完成,在eclipse中启动调试模式
2-4、再次返回到UCenter的控制台,点击应用管理,此时应该会看到绿色的“通信成功”字样.
2-5 注册端的代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("into do post"); String name= request.getParameter("name"); String pwd = request.getParameter("pwd"); String email="[email protected]"; System.out.println(name+","+pwd); Client uc = new Client(); String $return = uc.uc_user_register(name, pwd,email); System.out.println($return); int $uid = Integer.parseInt($return); if($uid <=0){ if($uid ==-1){System.out.println("用户名不合法");} else if($uid == -2){System.out.println("包含要允许注册的词语");} else if($uid == -3){System.out.println("用户名已经存在");} else if($uid == -4){System.out.println("Email 格式有误");} else if($uid == -5){System.out.println("Email 不允许注册");} else {System.out.println("未定义");} }else { System.out.println("OK"); } }
2-6 登录端的代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("into do post"); PrintWriter out=response.getWriter(); String name= request.getParameter("name"); String pwd = request.getParameter("pwd"); String email="[email protected]"; //System.out.println(name+","+pwd); request.setAttribute("username", name); Client uc = new Client(); String $result =uc.uc_user_login(name, pwd); String $ucsynlogin=""; LinkedList<String> rs = XMLHelper.uc_unserialize($result); String $username=null; String $password=null; int $uid=0; if(rs.size()>0){ $uid = Integer.parseInt(rs.get(0)); $username = rs.get(1); $password = rs.get(2); System.out.println($username+","+$password+","+$uid); if($uid > 0){ $ucsynlogin = uc.uc_user_synlogin($uid); }else if($uid == -1){ System.out.println("用户不存在,或者被删除"); }else if($uid == -2){ System.out.println("密码错误"); }else{ System.out.println("未定义"); } }// if //设置本地discuz登录的cookie信息,cookie存活时间 //直接访问论坛就可以有用户信息了 try{ response.setCharacterEncoding("utf-8"); //同步cookie信息 response.addHeader("P3P", "CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\""); Cookie auth = new Cookie("auth", uc.uc_authcode($password+"\t"+$uid, "ENCODE")); auth.setMaxAge(31536000); //添加到session request.getSession().setAttribute("user", $username); out.write($ucsynlogin); out.flush(); out.write("success"); out.flush(); }catch(Exception e){ e.printStackTrace(); } }
我们来看看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登录同步java网站web网站登录,中文乱码问题
到这里,我们又遇到了中文的问题了,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,其他情况自己改一下编码应该没问题。
参考资料 http://my.oschina.net/u/1274710/blog/165570
参考资料 http://www.cnblogs.com/netWild/archive/2013/06/28/3161164.html