discuz-ucenter_api_for_java
有懂discuz的吗?我需要在我自己的系统注册一个账号的时候,也把当前注册的账号放在discuz的用户里面。应该怎么做呀。需要discuz和java的接口吗?需要更改哪些东西。
所有的代码
1.UC.java
package com.fivestars.interfaces.bbs.api;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fivestars.interfaces.bbs.client.Client;
/**
* ================================================
* Discuz! Ucenter API for JAVA
* ================================================
* 此类用来同步UC Server发出的操作指令
* 可以根据业务需要添加相应的执行代码
*
* 作者:梁平
* 创建时间:2009-2-20
*/
public class UC extends HttpServlet{
private static final long serialVersionUID = -7377364931916922413L;
public static boolean IN_DISCUZ= true;
public static String UC_CLIENT_VERSION="1.5.0"; //note UCenter 版本标识
public static String UC_CLIENT_RELEASE="20081031";
public static boolean API_DELETEUSER=true; //note 用户删除 API 接口开关
public static boolean API_RENAMEUSER=true; //note 用户改名 API 接口开关
public static boolean API_GETTAG=true; //note 获取标签 API 接口开关
public static boolean API_SYNLOGIN=true; //note 同步登录 API 接口开关
public static boolean API_SYNLOGOUT=true; //note 同步登出 API 接口开关
public static boolean API_UPDATEPW=true; //note 更改用户密码 开关
public static boolean API_UPDATEBADWORDS=true; //note 更新关键字列表 开关
public static boolean API_UPDATEHOSTS=true; //note 更新域名解析缓存 开关
public static boolean API_UPDATEAPPS=true; //note 更新应用列表 开关
public static boolean API_UPDATECLIENT=true; //note 更新客户端缓存 开关
public static boolean API_UPDATECREDIT=true; //note 更新用户积分 开关
public static boolean API_GETCREDITSETTINGS=true; //note 向 UCenter 提供积分设置 开关
public static boolean API_GETCREDIT=true; //note 获取用户的某项积分 开关
public static boolean API_UPDATECREDITSETTINGS=true; //note 更新应用积分设置 开关
public static String API_RETURN_SUCCEED = "1";
public static String API_RETURN_FAILED = "-1";
public static String API_RETURN_FORBIDDEN = "-2";
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result = doAnswer(request, response);
response.getWriter().print(result);
}
/**
* 执行具体的Action
* 所有服务器发出的参数均可通过$get来获得。
* 注意: request本身是不能得到参数值的。
*
* @param request
* @param response
* @return 操作状态或操作结果
*/
private String doAnswer(HttpServletRequest request, HttpServletResponse response){
//处理
String $code = request.getParameter("code");
if($code==null) return API_RETURN_FAILED;
Map<String,String> $get = new HashMap<String, String>();
$code = new Client().uc_authcode($code, "DECODE");
parse_str($code, $get);
if($get.isEmpty()) {
return "Invalid Request";
}
if(time() - tolong($get.get("time")) > 3600) {
return "Authracation has expiried";
}
String $action = $get.get("action");
if($action==null) return API_RETURN_FAILED;
if($action.equals("test")) {
return API_RETURN_SUCCEED;
} else if($action.equals("deleteuser")) {
return API_RETURN_SUCCEED;
} else if($action.equals("renameuser")) {
return API_RETURN_SUCCEED;
} else if($action.equals("gettag")) {
if(!API_GETTAG ) return API_RETURN_FORBIDDEN;
//同步代码
return API_RETURN_SUCCEED;
} else if($action.equals("synlogin")) {
if(!API_SYNLOGIN ) return (API_RETURN_FORBIDDEN);
//note 同步登录 API 接口
//obclean();
response.addHeader("P3P","CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");
int $cookietime = 31536000;
Cookie user = new Cookie("loginuser",$get.get("username"));
user.setMaxAge($cookietime);
response.addCookie(user);
} else if($action.equals("synlogout")) {
if(!API_SYNLOGOUT ) return (API_RETURN_FORBIDDEN);
//note 同步登出 API 接口
//obclean();
response.addHeader("P3P"," CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");
//clearcookie();
Cookie user = new Cookie("loginuser","");
user.setMaxAge(0);
response.addCookie(user);
} else if($action.equals("updateclient")) {
if(!API_UPDATECLIENT ) return API_RETURN_FORBIDDEN;
//同步代码
return API_RETURN_SUCCEED;
} else if($action.equals("updatepw")) {
if(!API_UPDATEPW) return API_RETURN_FORBIDDEN;
//同步代码
return API_RETURN_SUCCEED;
} else if($action.equals("updatebadwords")) {
if(!API_UPDATEBADWORDS) return API_RETURN_FORBIDDEN;
//同步代码
return API_RETURN_SUCCEED;
} else if($action.equals("updatehosts")) {
if(!API_UPDATEHOSTS ) return API_RETURN_FORBIDDEN;
return API_RETURN_SUCCEED;
} else if($action.equals("updateapps")) {
if(!API_UPDATEAPPS ) return API_RETURN_FORBIDDEN;
return API_RETURN_SUCCEED;
} else if($action.equals("updatecredit")) {
//if(!UPDATECREDIT ) return API_RETURN_FORBIDDEN;
return API_RETURN_SUCCEED;
} else if($action.equals("getcreditsettings")) {
//if(!GETCREDITSETTINGS ) return API_RETURN_FORBIDDEN;
return "";//积分值
} else if($action.equals("updatecreditsettings")) {
if(!API_UPDATECREDITSETTINGS) return API_RETURN_FORBIDDEN;
//同步代码
return API_RETURN_SUCCEED;
} else {
return (API_RETURN_FORBIDDEN);
}
return "";
}
private void parse_str(String str, Map<String,String> sets){
if(str==null||str.length()<1)
return;
String[] ps = str.split("&");
for(int i=0;i<ps.length;i++){
String[] items = ps[i].split("=");
if(items.length==2){
sets.put(items[0], items[1]);
}else if(items.length ==1){
sets.put(items[0], "");
}
}
}
protected long time(){
return System.currentTimeMillis()/1000;
}
private static long tolong(Object s){
if(s!=null){
String ss = s.toString().trim();
if(ss.length()==0){
return 0L;
}else{
return Long.parseLong(ss);
}
}else{
return 0L;
}
}
}
2.Client.java
package com.fivestars.interfaces.bbs.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* ================================================
* Discuz! Ucenter API for JAVA
* ================================================
* UC Client 通用调用该类来实现与UC Server之间的通信。
* 该类实现与UC Server通信的所有接口函数
*
* 更多信息:http://code.google.com/p/discuz-ucenter-api-for-java/
* 作者:梁平 (no_ten@163.com)
* 创建时间:2009-2-20
*/
public class Client extends PHPFunctions{
public static boolean IN_UC = true;
public static String UC_IP = "127.0.0.1";
public static String UC_API = "http://localhost/uc";
public static String UC_CONNECT = "";
public static String UC_KEY = "123456";
public static String UC_APPID = "3";
public static String UC_CLIENT_VERSION = "1.0";
public static String UC_CLIENT_RELEASE = "20090212";
public static String UC_ROOT = ""; //note 用户中心客户端的根目录 UC_CLIENTROOT
public static String UC_DATADIR = UC_ROOT+"./data/"; //note 用户中心的数据缓存目录
public static String UC_DATAURL = "UC_API"+"/data"; //note 用户中心的数据 URL
public static String UC_API_FUNC = UC_CONNECT.equals("mysql") ? "uc_api_mysql" : "uc_api_post";
public static String[] uc_controls = {};
static {
InputStream in = Client.class.getClassLoader().getResourceAsStream("config.properties");
Properties properties = new Properties();
try {
properties.load(in);
UC_API = properties.getProperty("UC_API");
UC_IP = properties.getProperty("UC_IP");
UC_KEY = properties.getProperty("UC_KEY");
UC_APPID = properties.getProperty("UC_APPID");
UC_CONNECT = properties.getProperty("UC_CONNECT");
} catch (Exception e) {
e.printStackTrace();
}
}
protected String uc_serialize(String $arr, int $htmlon) {
//return xml_serialize($arr, $htmlon);
return $arr;
}
protected String uc_unserialize(String $s) {
//include_once UC_ROOT.'./lib/xml.class.php';
//return xml_unserialize($s);
return $s;
}
protected String uc_addslashes(String $string, int $force , boolean $strip ) {
// !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
// if(!MAGIC_QUOTES_GPC || $force) {
// if(is_array($string)) {
// foreach($string as $key => $val) {
// $string[$key] = uc_addslashes($val, $force, $strip);
// }
// } else {
// $string = addslashes($strip ? stripslashes($string) : $string);
// }
// }
return $string;
}
protected String daddslashes(String $string, int $force) {
return uc_addslashes($string, $force, false);
}
protected String uc_stripslashes(String $string) {
// !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
// if(MAGIC_QUOTES_GPC) {
// return stripslashes($string);
// } else {
return $string;
// }
}
public String uc_api_post(String $module, String $action, Map<String,Object> $arg ) {
StringBuffer $s = new StringBuffer();
String $sep = "";
//foreach($arg as $k => $v) {
for (String $k : $arg.keySet()) {
//$k = ($k);
Object $v = $arg.get($k);
$k = urlencode($k);
if($v.getClass().isAssignableFrom(Map.class)) {
String $s2 = "";
String $sep2 = "";
//foreach($v as $k2 => $v2) {
for(String $k2 : ((Map<String,Object>)$v).keySet() ){
Object $v2 = ((Map<String,Object>)$v).get($k2);
$k2 = urlencode($k2);
$s2 += $sep2+"{"+$k+"}["+$k2+"]="+urlencode(uc_stripslashes( String.valueOf( $v2 )));
$sep2 = "&";
}
$s.append($sep).append($s2);
} else {
$s.append($sep).append($k).append("=").append(urlencode(uc_stripslashes( String.valueOf($v) )));
}
$sep = "&";
}
String $postdata = uc_api_requestdata($module, $action, $s.toString(),"");
return uc_fopen2(UC_API+"/index.php", 500000, $postdata, "", true, UC_IP, 20, true);
}
/**
* 构造发送给用户中心的请求数据
*
* @param string $module 请求的模块
* @param string $action 请求的动作
* @param string $arg 参数(会加密的方式传送)
* @param string $extra 附加参数(传送时不加密)
* @return string
*/
protected String uc_api_requestdata(String $module, String $action, String $arg, String $extra) {
String $input = uc_api_input($arg);
String $post = "m="+$module+"&a="+$action+"&inajax=2&release="+UC_CLIENT_RELEASE+"&input="+$input+"&appid="+UC_APPID+$extra;
return $post;
}
protected String uc_api_url(String $module, String $action, String $arg, String $extra) {
String $url = UC_API+"/index.php?"+uc_api_requestdata($module, $action, $arg, $extra);
return $url;
}
public String uc_api_input(String $data) {
//String $s = $data;
//String $s = urlencode(uc_authcode($data+"&agent="+md5($_SERVER["HTTP_USER_AGENT"])+"&time="+time(), "ENCODE", UC_KEY));
//String $s = urlencode(uc_authcode($data+"&agent="+md5("Java/1.5.0_01")+"&time="+time(), "ENCODE", UC_KEY));
String $s = urlencode(uc_authcode($data+"&agent="+md5("")+"&time="+time(), "ENCODE", UC_KEY));
return $s;
}
/**
* MYSQL 方式取指定的模块和动作的数据
*
* @param string $model 请求的模块
* @param string $action 请求的动作
* @param string $args 参数(会加密的方式传送)
* @return mix
*/
public String uc_api_mysql(String $model, String $action, Map $args) {
// global $uc_controls;
// if(empty($uc_controls[$model])) {
// include_once UC_ROOT.'./lib/db.class.php';
// include_once UC_ROOT.'./model/base.php';
// include_once UC_ROOT."./control/$model.php";
// eval("\$uc_controls['$model'] = new {$model}control();");
// }
if($action.charAt(0) != '_') {
// $args = uc_addslashes($args, 1, true);
// $action = "on"+$action;
// $uc_controls[$model]->input = $args;
// return $uc_controls[$model]->$action($args);
return null;
} else {
return "";
}
}
/**
* 字符串加密以及解密函数
*
* @param string $string 原文或者密文
* @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE
* @param string $key 密钥
* @param int $expiry 密文有效期, 加密时候有效, 单位 秒,0 为永久有效
* @return string 处理后的 原文或者 经过 base64_encode 处理后的密文
*
* @example
*
* $a = authcode('abc', 'ENCODE', 'key');
* $b = authcode($a, 'DECODE', 'key'); // $b(abc)
*
* $a = authcode('abc', 'ENCODE', 'key', 3600);
* $b = authcode('abc', 'DECODE', 'key'); // 在一个小时内,$b(abc),否则 $b 为空
*/
public String uc_authcode(String $string, String $operation){
return uc_authcode($string, $operation, null);
}
public String uc_authcode(String $string, String $operation, String $key){
return uc_authcode($string, $operation, $key, 0);
}
public String uc_authcode(String $string, String $operation, String $key,int $expiry ) {
int $ckey_length = 4; //note 随机密钥长度 取值 0-32;
//note 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
//note 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
//note 当此值为 0 时,则不产生随机密钥
$key = md5( $key!=null ? $key : UC_KEY);
String $keya = md5(substr($key, 0, 16));
String $keyb = md5(substr($key, 16, 16));
String $keyc = $ckey_length > 0? ($operation.equals("DECODE") ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : "";
String $cryptkey = $keya + md5( $keya + $keyc);
int $key_length = $cryptkey.length();
$string = $operation.equals("DECODE") ? base64_decode(substr($string, $ckey_length)) : sprintf("%010d", $expiry>0 ? $expiry + time() : 0)+substr(md5($string+$keyb), 0, 16)+$string;
int $string_length = $string.length();
StringBuffer $result1 = new StringBuffer();
int[] $box = new int[256];
for(int i=0;i<256;i++){
$box[i] = i;
}
int[] $rndkey = new int[256];
for(int $i = 0; $i <= 255; $i++) {
$rndkey[$i] = (int)$cryptkey.charAt($i % $key_length);
}
int $j=0;
for(int $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
int $tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
$j=0;
int $a=0;
for(int $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
int $tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result1.append((char)( ((int)$string.charAt($i)) ^ ($box[($box[$a] + $box[$j]) % 256])));
}
if($operation.equals("DECODE")) {
String $result = $result1.substring(0, $result1.length());
if((Integer.parseInt(substr($result.toString(), 0, 10)) == 0 || Long.parseLong(substr($result.toString(), 0, 10)) - time() > 0) && substr($result.toString(), 10, 16).equals( substr(md5(substr($result.toString(), 26)+ $keyb), 0, 16))) {
return substr($result.toString(), 26);
} else {
return "";
}
} else {
return $keyc+base64_encode($result1.toString()).replaceAll("=", "");
}
}
/**
* 远程打开URL
* @param string $url 打开的url, 如 http://www.baidu.com/123.htm
* @param int $limit 取返回的数据的长度
* @param string $post 要发送的 POST 数据,如uid=1&password=1234
* @param string $cookie 要模拟的 COOKIE 数据,如uid=123&auth=a2323sd2323
* @param bool $bysocket TRUE/FALSE 是否通过SOCKET打开
* @param string $ip IP地址
* @param int $timeout 连接超时时间
* @param bool $block 是否为阻塞模式 defaul valuet:true
* @return 取到的字符串
*/
protected String uc_fopen2(String $url, int $limit , String $post, String $cookie, boolean $bysocket, String $ip, int $timeout, boolean $block) {
// long $__times__ = isset($_GET["__times__"]) ? intval($_GET["__times__"]) + 1 : 1;
// if($__times__ > 2) {
// return "";
// }
$url += $url.indexOf("?")>0? "&" : "?" +"__times__=1";
return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block);
}
protected String uc_fopen(String $url, int $limit, String $post, String $cookie, boolean $bysocket ,String $ip , int $timeout , boolean $block ) {
String $return = "";
URL $matches;
String $host="";
String $path="";
int $port = 80;
try {
$matches = new URL($url);
$host = $matches.getHost();
$path = $matches.getPath()!=null? $matches.getPath()+($matches.getQuery()!=null?"?"+$matches.getQuery():""):"/";
if( $matches.getPort()>0 ) $port = $matches.getPort();
} catch (MalformedURLException e1) {
}
StringBuffer $out = new StringBuffer();
if($post!=null && $post.length()>0) {
$out.append("POST ").append($path).append(" HTTP/1.0\r\n");
$out.append("Accept: */*\r\n");
$out.append("Accept-Language: zh-cn\r\n");
$out.append("Content-Type: application/x-www-form-urlencoded\r\n");
$out.append("User-Agent: \r\n");
$out.append("Host: ").append($host).append("\r\n");
$out.append("Content-Length: ").append($post.length()).append("\r\n");
$out.append("Connection: Close\r\n");
$out.append("Cache-Control: no-cache\r\n");
$out.append("Cookie: \r\n\r\n");
$out.append($post);
} else {
$out.append("GET $path HTTP/1.0\r\n");
$out.append( "Accept: */*\r\n");
//$out .= "Referer: $boardurl\r\n";
$out.append("Accept-Language: zh-cn\r\n");
$out.append("User-Agent: Java/1.5.0_01\r\n");
$out.append("Host: $host\r\n");
$out.append("Connection: Close\r\n");
$out.append("Cookie: $cookie\r\n\r\n");
}
try{
Socket $fp = new Socket($ip!=null && $ip.length()>10? $ip : $host, $port );
if(!$fp.isConnected()) {
return "";//note $errstr : $errno \r\n
} else {
OutputStream os = $fp.getOutputStream();
os.write($out.toString().getBytes());
InputStream ins = $fp.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
while (true) {
String $header = reader.readLine();
if($header == null || $header.equals("") || $header == "\r\n" || $header == "\n") {
break;
}
}
while (true) {
String $data = reader.readLine();
if($data == null || $data.equals("") ) {
break;
}else{
$return+=$data;
}
}
$fp.close();
}
}catch (IOException e) {
}
return $return;
}
public String uc_app_ls() {
String $return = call_user_func(UC_API_FUNC, "app", "ls", null);
return UC_CONNECT.equals("mysql") ? $return : uc_unserialize($return);
}
/**
* 用户注册
*
* @param string $username 用户名
* @param string $password 密码
* @param string $email Email
* @param int $questionid 安全提问
* @param string $answer 安全提问答案
* @return int
-1 : 用户名不合法
-2 : 包含不允许注册的词语
-3 : 用户名已经存在
-4 : email 格式有误
-5 : email 不允许注册
-6 : 该 email 已经被注册
>1 : 表示成功,数值为 UID
*/
public String uc_user_register(String $username, String $password, String $email){
return uc_user_register($username, $password, $email, "", "");
}
public String uc_user_register(String $username, String $password, String $email, String $questionid, String $answer) {
Map<String ,Object> args = new HashMap<String, Object>();
args.put("username",$username);
args.put("password",$password);
args.put("email",$email);
args.put("questionid",$questionid);
args.put("answer",$answer);
return call_user_func(UC_API_FUNC, "user", "register", args);
}
/**
* 用户登陆检查
*
* @param string $username 用户名/uid
* @param string $password 密码
* @param int $isuid 是否为uid
* @param int $checkques 是否使用检查安全问答
* @param int $questionid 安全提问
* @param string $answer 安全提问答案
* @return array (uid/status, username, password, email)
数组第一项
1 : 成功
-1 : 用户不存在,或者被删除
-2 : 密码错
*/
public String uc_user_login(String $username, String $password){
return uc_user_login($username, $password, 0, 0);
}
public String uc_user_login(String $username, String $password, int $isuid , int $checkques ){
return uc_user_login($username, $password, $isuid, $checkques, "","");
}
public String uc_user_login(String $username, String $password, int $isuid , int $checkques , String $questionid, String $answer) {
Map<String,Object> args = new HashMap<String, Object>();
args.put("username",$username);
args.put("password",$password);
args.put("isuid",$isuid);
args.put("checkques",$checkques);
args.put("questionid", $questionid);
args.put("answer",$answer);
String $return = call_user_func(UC_API_FUNC, "user", "login", args);
return UC_CONNECT .equals("mysql") ? $return : uc_unserialize($return);
}
/**
* 进入同步登录代码
*
* @param int $uid 用户ID
* @return string HTML代码
*/
public String uc_user_synlogin(int $uid) {
Map<String, Object> args = new HashMap<String, Object>();
args.put( "uid",$uid);
String $return = uc_api_post("user", "synlogin", args);
return $return;
}
/**
* 进入同步登出代码
*
* @return string HTML代码
*/
public String uc_user_synlogout() {
String $return = uc_api_post("user", "synlogout", new HashMap<String, Object>());
return $return;
}
/**
* 取得用户数据
*
* @param string $username 用户名
* @param int $isuid 是否为UID
* @return array (uid, username, email)
*/
public String uc_get_user(String $username, int $isuid) {
Map<String,Object> args = new HashMap<String, Object>();
args.put("username",$username );
args.put("isuid", $isuid );
String $return = call_user_func(UC_API_FUNC, "user", "get_user", args);
return UC_CONNECT.equals("mysql") ? $return : uc_unserialize($return);
}
/**
* 编辑用户
*
* @param string $username 用户名
* @param string $oldpw 旧密码
* @param string $newpw 新密码
* @param string $email Email
* @param int $ignoreoldpw 是否忽略旧密码, 忽略旧密码, 则不进行旧密码校验.
* @param int $questionid 安全提问
* @param string $answer 安全提问答案
* @return int
1 : 修改成功
0 : 没有任何修改
-1 : 旧密码不正确
-4 : email 格式有误
-5 : email 不允许注册
-6 : 该 email 已经被注册
-7 : 没有做任何修改
-8 : 受保护的用户,没有权限修改
*/
public String uc_user_edit(String $username, String $oldpw, String $newpw, String $email, int $ignoreoldpw, String $questionid, String $answer) {
Map<String,Object> args = new HashMap<String, Object>();
args.put("username", $username);
args.put("oldpw",$oldpw);
args.put("newpw",$newpw);
args.put("email",$email);
args.put("ignoreoldpw",$ignoreoldpw);
args.put("questionid", $questionid);
args.put("answer", $answer);
return call_user_func(UC_API_FUNC, "user", "edit", args);
}
/**
* 删除用户
*
* @param string/array $uid 用户的 UID
* @return int
>0 : 成功
0 : 失败
*/
public String uc_user_delete(String $uid) {
Map<String,Object> args = new HashMap<String, Object>();
args.put("uid",$uid);
return call_user_func(UC_API_FUNC, "user", "delete", args);
}
/**
* 删除用户头像
*
* @param string/array $uid 用户的 UID
*/
public String uc_user_deleteavatar(String $uid) {
Map<String,Object> args = new HashMap<String, Object>();
args.put("uid",$uid);
return uc_api_post("user", "deleteavatar", args);
}
}
3.PHPFunctions.java
package com.fivestars.interfaces.bbs.client;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import com.fivestars.interfaces.bbs.util.Base64;
/**
* ================================================
* Discuz! Ucenter API for JAVA
* ================================================
* 构造本接口运行所需要PHP的内置函数
*
* 更多信息:http://code.google.com/p/discuz-ucenter-api-for-java/
* 作者:梁平 (no_ten@163.com)
* 创建时间:2009-2-20
*/
public abstract class PHPFunctions {
//JAVA EXTRA METHOD
protected String urlencode(String value){
return URLEncoder.encode(value);
}
protected String md5(String input){
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
return byte2hex(md.digest(input.getBytes()));
}
protected String md5(long input){
return md5(String.valueOf(input));
}
protected String base64_decode(String input){
try {
return new String(com.fivestars.interfaces.bbs.util.Base64.decode(input.toCharArray()),"iso-8859-1");
} catch (Exception e) {
return e.getMessage();
}
}
protected String base64_encode(String input){
try {
return new String(Base64.encode(input.getBytes("iso-8859-1")));
} catch (Exception e) {
return e.getMessage();
}
}
protected String byte2hex(byte[] b) {
StringBuffer hs = new StringBuffer();
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1)
hs.append("0").append(stmp);
else
hs.append(stmp);
}
return hs.toString();
}
protected String substr(String input,int begin, int length){
return input.substring(begin, begin+length);
}
protected String substr(String input,int begin){
if(begin>0){
return input.substring(begin);
}else{
return input.substring(input.length()+ begin);
}
}
protected long microtime(){
return System.currentTimeMillis();
}
protected long time(){
return System.currentTimeMillis()/1000;
}
protected String sprintf(String format, long input){
String temp = "0000000000"+input;
return temp.substring(temp.length()-10);
}
protected String call_user_func(String function, String model, String action, Map<String,Object> args){
if("uc_api_mysql".equals(function)){
return this.uc_api_mysql(model, action, args);
}
if("uc_api_post".equals(function)){
return this.uc_api_post(model, action, args);
}
return "";
}
public abstract String uc_api_post(String $module, String $action, Map<String,Object> $arg );
public abstract String uc_api_mysql(String $model, String $action, Map $args);
}
4.Base64.java
/* ========================================================================
* JCommon : a free general purpose class library for the Java(tm) platform
* ========================================================================
*
* (C) Copyright 2000-2004, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -------------------------------------
* AbstractElementDefinitionHandler.java
* -------------------------------------
* (C)opyright 2003, by Thomas Morgner and Contributors.
*
* Original Author: Kevin Kelley <kelley@ruralnet.net> -
* 30718 Rd. 28, La Junta, CO, 81050 USA. //
*
* $Id: Base64.java,v 1.5 2004/01/01 23:59:29 mungady Exp $
*
* Changes
* -------------------------
* 23.09.2003 : Initial version
*
*/
package com.fivestars.interfaces.bbs.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
/**
* Provides encoding of raw bytes to base64-encoded characters, and
* decoding of base64 characters to raw bytes.
* date: 06 August 1998
* modified: 14 February 2000
* modified: 22 September 2000
*
* @author Kevin Kelley (kelley@ruralnet.net)
* @version 1.3
*/
public class Base64 {
/**
* returns an array of base64-encoded characters to represent the
* passed data array.
*
* @param data the array of bytes to encode
* @return base64-coded character array.
*/
public static char[] encode(byte[] data) {
char[] out = new char[((data.length + 2) / 3) * 4];
//
// 3 bytes encode to 4 chars. Output is always an even
// multiple of 4 characters.
//
for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
boolean quad = false;
boolean trip = false;
int val = (0xFF & data[i]);
val <<= 8;
if ((i + 1) < data.length) {
val |= (0xFF & data[i + 1]);
trip = true;
}
val <<= 8;
if ((i + 2) < data.length) {
val |= (0xFF & data[i + 2]);
quad = true;
}
out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
val >>= 6;
out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
val >>= 6;
out[index + 1] = alphabet[val & 0x3F];
val >>= 6;
out[index + 0] = alphabet[val & 0x3F];
}
return out;
}
/**
* Decodes a BASE-64 encoded stream to recover the original
* data. White space before and after will be trimmed away,
* but no other manipulation of the input will be performed.
*
* As of version 1.2 this method will properly handle input
* containing junk characters (newlines and the like) rather
* than throwing an error. It does this by pre-parsing the
* input and generating from that a count of VALID input
* characters.
**/
public static byte[] decode(char[] data) {
// as our input could contain non-BASE64 data (newlines,
// whitespace of any sort, whatever) we must first adjust
// our count of USABLE data so that...
// (a) we don't misallocate the output array, and
// (b) think that we miscalculated our data length
// just because of extraneous throw-away junk
int tempLen = data.length;
for (int ix = 0; ix < data.length; ix++) {
if ((data[ix] > 255) || codes[data[ix]] < 0)
--tempLen; // ignore non-valid chars and padding
}
// calculate required length:
// -- 3 bytes for every 4 valid base64 chars
// -- plus 2 bytes if there are 3 extra base64 chars,
// or plus 1 byte if there are 2 extra.
int len = (tempLen / 4) * 3;
if ((tempLen % 4) == 3)
len += 2;
if ((tempLen % 4) == 2)
len += 1;
byte[] out = new byte[len];
int shift = 0; // # of excess bits stored in accum
int accum = 0; // excess bits
int index = 0;
// we now go through the entire array (NOT using the 'tempLen' value)
for (int ix = 0; ix < data.length; ix++) {
int value = (data[ix] > 255) ? -1 : codes[data[ix]];
if (value >= 0)// skip over non-code
{
accum <<= 6; // bits shift up by 6 each time thru
shift += 6; // loop, with new bits being put in
accum |= value; // at the bottom.
if (shift >= 8)// whenever there are 8 or more shifted in,
{
shift -= 8; // write them out (from the top, leaving any
out[index++] = // excess at the bottom for next iteration.
(byte) ((accum >> shift) & 0xff);
}
}
// we will also have skipped processing a padding null byte ('=') here;
// these are used ONLY for padding to an even length and do not legally
// occur as encoded data. for this reason we can ignore the fact that
// no index++ operation occurs in that special case: the out[] array is
// initialized to all-zero bytes to start with and that works to our
// advantage in this combination.
}
// if there is STILL something wrong we just have to throw up now!
if (index != out.length) {
throw new Error("Miscalculated data length (wrote " +
index + " instead of " + out.length + ")");
}
return out;
}
//
// code characters for values 0..63
//
private static char[] alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
//
// lookup table for converting base64 characters to value in range 0..63
//
private static byte[] codes = new byte[256];
static {
for (int i = 0; i < 256; i++)
codes[i] = -1;
for (int i = 'A'; i <= 'Z'; i++)
codes[i] = (byte) (i - 'A');
for (int i = 'a'; i <= 'z'; i++)
codes[i] = (byte) (26 + i - 'a');
for (int i = '0'; i <= '9'; i++)
codes[i] = (byte) (52 + i - '0');
codes['+'] = 62;
codes['/'] = 63;
}
///
// remainder (main method and helper functions) is
// for testing purposes only, feel free to clip it.
///
public static void main(String[] args) {
boolean decode = false;
if (args.length == 0) {
System.out.println("usage: java Base64 [-d[ecode]] filename");
System.exit(0);
}
for (int i = 0; i < args.length; i++) {
if ("-decode".equalsIgnoreCase(args[i]))
decode = true;
else if ("-d".equalsIgnoreCase(args[i]))
decode = true;
}
String filename = args[args.length - 1];
File file = new File(filename);
if (!file.exists()) {
System.out.println("Error: file '" + filename + "' doesn't exist!");
System.exit(0);
}
if (decode) {
char[] encoded = readChars(file);
byte[] decoded = decode(encoded);
writeBytes(file, decoded);
}
else {
byte[] decoded = readBytes(file);
char[] encoded = encode(decoded);
writeChars(file, encoded);
}
}
private static byte[] readBytes(File file) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
InputStream fis = new FileInputStream(file);
InputStream is = new BufferedInputStream(fis);
int count = 0;
byte[] buf = new byte[16384];
while ((count = is.read(buf)) != -1) {
if (count > 0)
baos.write(buf, 0, count);
}
is.close();
}
catch (Exception e) {
e.printStackTrace();
}
return baos.toByteArray();
}
private static char[] readChars(File file) {
CharArrayWriter caw = new CharArrayWriter();
try {
Reader fr = new FileReader(file);
Reader in = new BufferedReader(fr);
int count = 0;
char[] buf = new char[16384];
while ((count = in.read(buf)) != -1) {
if (count > 0)
caw.write(buf, 0, count);
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
return caw.toCharArray();
}
private static void writeBytes(File file, byte[] data) {
try {
OutputStream fos = new FileOutputStream(file);
OutputStream os = new BufferedOutputStream(fos);
os.write(data);
os.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private static void writeChars(File file, char[] data) {
try {
Writer fos = new FileWriter(file);
Writer os = new BufferedWriter(fos);
os.write(data);
os.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
///
// end of test code.
///
}
5.XMLHelper.java
package com.fivestars.interfaces.bbs.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.LinkedList;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.sun.org.apache.xerces.internal.parsers.DOMParser;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
/**
* ================================================
* Discuz! Ucenter API for JAVA
* ================================================
* XML工具类,处理UC Client接收到返回结果。
* UC Client会收到UC Server返回的XML结果
* 该类将XML中的数据提取成一个List按顺序读取即可。
*
* 更多信息:http://code.google.com/p/discuz-ucenter-api-for-java/
* 作者:梁平 (no_ten@163.com)
* 创建时间:2009-2-20
*/
public class XMLHelper {
public static LinkedList<String> uc_unserialize(String input){
LinkedList<String> result = new LinkedList<String>();
DOMParser parser = new DOMParser();
try {
parser.parse(new InputSource(new StringReader(input)));
Document doc = parser.getDocument();
NodeList nl = doc.getChildNodes().item(0).getChildNodes();
int length = nl.getLength();
for(int i=0;i<length;i++){
if(nl.item(i).getNodeType()==Document.ELEMENT_NODE)
result.add(nl.item(i).getTextContent());
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
6.Test.java
package test;
import java.util.LinkedList;
import com.fivestars.interfaces.bbs.client.Client;
import com.fivestars.interfaces.bbs.util.XMLHelper;
/**
* ================================================
* Discuz! Ucenter API for JAVA
* ================================================
* 测试类
* 示例:本类实现在如何实现在登入/登出,以及注册。
*
* 更多信息:http://code.google.com/p/discuz-ucenter-api-for-java/
* 作者:梁平 (no_ten@163.com)
* 创建时间:2009-2-20
*/
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
testLogin();
Client uc = new Client();
String s = uc.uc_authcode("8485m7QEfsvnOg9tKGvAsxlwXpAzZU6LhFA04pD6N0XIYG1cJVDh2Th83Qcci130UPHbXp+UNG0","DECODE");
System.out.println(s);
}
public static void testLogin(){
Client e = new Client();
String result = e.uc_user_login("admin", "123456");
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) {
System.out.println("登录成功");
System.out.println($username);
System.out.println($password);
System.out.println($email);
String $ucsynlogin = e.uc_user_synlogin($uid);
System.out.println("登录成功"+$ucsynlogin);
//本地登陆代码
//TODO ... ....
} 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+"1");
}
}
public static void testLogout(){
Client uc = new Client();
//setcookie('Example_auth', '', -86400);
// 生成同步退出的代码
String $ucsynlogout = uc.uc_user_synlogout();
System.out.println("退出成功"+$ucsynlogout);
}
public static void testRegister(){
Client uc = new Client();
//setcookie('Example_auth', '', -86400);
// 生成同步退出的代码
String $returns = uc.uc_user_register("cccc", "ccccc" ,"ccc@abc.com" );
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);
}
}
}
有懂discuz的吗?我需要在我自己的系统注册一个账号的时候,也把当前注册的账号放在discuz的用户里面。应该怎么做呀。需要discuz和java的接口吗?需要更改哪些东西。