网易微博最近也开放了它的开发平台
http://open.t.163.com,其中java版的oauth认证和新浪微博的很类似(貌似都是从twitter那边copy过来的)。但说句实话,网易java版的sdk和新浪微博的比起来,的确上手比较麻烦,里面提供的example都是把access token写死,作为参数,具体的代码如下:

 public static void main(String[] args)
public static void main(String[] args) {
{
 
        
 System.setProperty("tblog4j.oauth.consumerKey", "EJ0GpH9mtU584qtY");
        System.setProperty("tblog4j.oauth.consumerKey", "EJ0GpH9mtU584qtY");
 System.setProperty("tblog4j.oauth.consumerSecret", "EgIdvwgF6UXc6WMZs6jTv5ivZcNVDvnT");
        System.setProperty("tblog4j.oauth.consumerSecret", "EgIdvwgF6UXc6WMZs6jTv5ivZcNVDvnT");
 
        
 TBlog tblog = new TBlog();
        TBlog tblog = new TBlog();
 
        
 tblog.setToken("46f29fb418bdb14044bf39d2cad49f81", "f0c81ad9783f1s427da38312c0cc910c");
        tblog.setToken("46f29fb418bdb14044bf39d2cad49f81", "f0c81ad9783f1s427da38312c0cc910c");
 
        

 try
        try  {
{
 
            
 tblog.updateStatus("update status from Java SDK");
            tblog.updateStatus("update status from Java SDK");
 
            

 } catch (TBlogException e)
        } catch (TBlogException e)  {
{
 e.printStackTrace();
            e.printStackTrace();
 }
        }
 }
    }
完全没有体现出oauth的完整认证过程,access token(就是46f29fb418bdb14044bf39d2cad49f81,f0c81ad9783f1s427da38312c0cc910c"两段字符串)是怎么来的,完全没有演示的过程,搞得我做这个开发的时候只能摸黑,其实oauth的完整过程是这样的:
 
OAuth流程图
    - A:消费方请求Request Token
    
- B:服务提供者授权Request Token
    
- C:消费方定向用户到服务提供者
    
- D:获得用户授权后,服务提供者定向用户到消费方
    
- E:消费方请求Access Token
    
- F:服务提供者授权Access Token
    
- G:消费方访问受保护的资源 
具体的请去围观这篇文章http://huoding.com/2010/10/10/8.
由于开发受阻,只好求助它的兄弟sdk,那就是新浪微博的sdk,但两者虽然相似度很高,但到底在细节处还是有所不同,下面就是我仿造新浪微博网页oauth认证的网易版。
这个过程首先是要在网易开发平台申请消费者开发的key和secret字符串,谁都可以去上面的网易开发平台申请:申请到的画面如下:

然后就可以构造一个jsp的页面,这个页面就是调用oauth认证的,我这个jsp叫call.jsp,具体的jsp代码如下:
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
    pageEncoding="ISO-8859-1"%>
 <%@ page language="java" import="t4j.*" %>
<%@ page language="java" import="t4j.*" %>
 <%@ page language="java" import="t4j.http.*" %>
<%@ page language="java" import="t4j.http.*" %>    
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
<html>
 <head>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 <title>Insert title here</title>
<title>Insert title here</title>
 </head>
</head>
 <body>
<body>
 <%
<%
 System.setProperty("tblog4j.oauth.consumerKey", "EJ0GpH9mtU123xxx");
System.setProperty("tblog4j.oauth.consumerKey", "EJ0GpH9mtU123xxx");
 System.setProperty("tblog4j.oauth.consumerSecret", "EgIdvwgF6UXc6WMZs6jTv5ivZcxxxxxx");
System.setProperty("tblog4j.oauth.consumerSecret", "EgIdvwgF6UXc6WMZs6jTv5ivZcxxxxxx");

 TBlog tblog = new TBlog();
TBlog tblog = new TBlog();

 try
try  {
{
 RequestToken requestToken = tblog.getOAuthRequestToken();
    RequestToken requestToken = tblog.getOAuthRequestToken();
 session.setAttribute("requestToken",requestToken);
    session.setAttribute("requestToken",requestToken);
 String url = "http://api.t.163.com/oauth/authenticate?oauth_token="+requestToken.getToken()+"&oauth_token_secret="+requestToken.getTokenSecret()+"&oauth_callback=http%3A%2F%2Flocalhost%3A8080%2F163%2Fcallback.jsp";
    String url = "http://api.t.163.com/oauth/authenticate?oauth_token="+requestToken.getToken()+"&oauth_token_secret="+requestToken.getTokenSecret()+"&oauth_callback=http%3A%2F%2Flocalhost%3A8080%2F163%2Fcallback.jsp";
 
    
 response.sendRedirect(url);
    response.sendRedirect(url);

 } catch (TBlogException e1)
} catch (TBlogException e1)  {
{
 // TODO Auto-generated catch block
    // TODO Auto-generated catch block
 e1.printStackTrace();
    e1.printStackTrace();
 }
}
 %>
%>
 </body>
</body>
 </html>
</html>
这个页面就是把申请来的consumerKey和consumerSecret传到一个TBlog对象,这个对象就是网易微博的接口对象了,所有oauth认证以及网易微博的操作api都在这个类中。传递过去后就能够得到request token,同时把requestToken存到session里面,方便后面的页面使用。接下来就是oauth的认证了,需要把requestToken和requestTokenSecret(两个字符串,在requestToken对象中)传递到网易的授权页面,记得带上oauth_callback参数,这个参数是通过认证后网易回调的页面,说明白一点,就是通过认证了,网易就会自己跳回到你oauth_callback里面传递的这个页面。然后就跳到网易的认证页面了。

需要输入网易通行证的用户名和密码,登录后就到了认证的页面了

点击允许后,就会跳回到oauth_callback参数传递的页面,我这个页面就是callback.jsp,代码如下:
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
    pageEncoding="ISO-8859-1"%>
 <%@ page language="java" import="t4j.*" %>
<%@ page language="java" import="t4j.*" %>
 <%@ page language="java" import="t4j.http.*" %>
<%@ page language="java" import="t4j.http.*" %>    
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
<html>
 <head>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 <title>Insert title here</title>
<title>Insert title here</title>
 </head>
</head>
 <body>
<body>
 <%
<%
 RequestToken requestToken = (RequestToken)session.getAttribute("requestToken");
RequestToken requestToken = (RequestToken)session.getAttribute("requestToken");
 TBlog tblog = new TBlog();
TBlog tblog = new TBlog();
 AccessToken token = tblog.getOAuthAccessToken(requestToken);
AccessToken token = tblog.getOAuthAccessToken(requestToken);
 tblog.setToken(token.getToken(),token.getTokenSecret());
tblog.setToken(token.getToken(),token.getTokenSecret());


 try
try  {
{
 
    
 out.println(tblog.updateStatus("update status from Java SDK").getId());
    out.println(tblog.updateStatus("update status from Java SDK").getId());
 
    

 } catch (TBlogException e)
} catch (TBlogException e)  {
{
 e.printStackTrace();
    e.printStackTrace();
 }
}

 %>
%>

 </body>
</body>
 </html>
</html>
在这个页面就可以去到通过了认证的AccessToken,有了这个,就算是通过了oauth认证,可以操作网易微博的各种资源了。requestToken存在session的意义就是为了在这个页面可以去到,并根据这个requestToken得到AccessToken,如果不经过网易的那个认证页面,直接用requestToken是得不到AccessToken(是的,我试过了直接取,没用的)。上面updateStaus就是发一条微博到网易去。
本来到这边就算完成了,但是如果我们需要通过接口搜索网易微博的内容时,比如这样:
 List<Status> list = tblog.searchStatus("情人节");
List<Status> list = tblog.searchStatus("情人节");
那么你遇到的就是像一个人的情人节那样可耻的失败,当然上面如果是英语,是不会有问题的,但中文(中国程序员满脸都是泪,心里都是苦),错误代码是这样的:
 [Wed Feb 16 21:15:25 CST 2011]Request:
[Wed Feb 16 21:15:25 CST 2011]Request: 
 [Wed Feb 16 21:15:25 CST 2011]GET http://api.t.163.com/search.json?q=情人节
[Wed Feb 16 21:15:25 CST 2011]GET http://api.t.163.com/search.json?q=情人节
 [Wed Feb 16 21:15:25 CST 2011]OAuth base string:GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0%26q%3D%25E6%2583%2585%25E4%25BA%25BA%25E8%258A%2582
[Wed Feb 16 21:15:25 CST 2011]OAuth base string:GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0%26q%3D%25E6%2583%2585%25E4%25BA%25BA%25E8%258A%2582
 [Wed Feb 16 21:15:25 CST 2011]OAuth signature:XMJW2PnNi1TuL1kSkiwCmBbSejA=
[Wed Feb 16 21:15:25 CST 2011]OAuth signature:XMJW2PnNi1TuL1kSkiwCmBbSejA=
 [Wed Feb 16 21:15:25 CST 2011]Authorization: OAuth oauth_consumer_key="EJ0GpH9mtU584qtY",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1297862125",oauth_nonce="1981498615",oauth_version="1.0",oauth_token="3d5ec3c98e57d20c40c458bfe6999d66",oauth_signature="XMJW2PnNi1TuL1kSkiwCmBbSejA%3D"
[Wed Feb 16 21:15:25 CST 2011]Authorization: OAuth oauth_consumer_key="EJ0GpH9mtU584qtY",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1297862125",oauth_nonce="1981498615",oauth_version="1.0",oauth_token="3d5ec3c98e57d20c40c458bfe6999d66",oauth_signature="XMJW2PnNi1TuL1kSkiwCmBbSejA%3D"
 [Wed Feb 16 21:15:25 CST 2011]TBlog-Client-URL: http://open.t.163.com
[Wed Feb 16 21:15:25 CST 2011]TBlog-Client-URL: http://open.t.163.com
 [Wed Feb 16 21:15:25 CST 2011]Accept-Encoding: gzip
[Wed Feb 16 21:15:25 CST 2011]Accept-Encoding: gzip
 [Wed Feb 16 21:15:25 CST 2011]User-Agent: tblog4j http://open.t.163.com
[Wed Feb 16 21:15:25 CST 2011]User-Agent: tblog4j http://open.t.163.com
 [Wed Feb 16 21:15:25 CST 2011]TBlog-Client-Version: 1.0
[Wed Feb 16 21:15:25 CST 2011]TBlog-Client-Version: 1.0
 t4j.TBlogException: 401:Authentication credentials were missing or incorrect.
t4j.TBlogException: 401:Authentication credentials were missing or incorrect.


 {"request":"/search.json?q=?é????","error":"oauth_signature=XMJW2PnNi1TuL1kSkiwCmBbSejA= oauth_signature_base_string=GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0 oauth_problem=signature_invalid oauth_signature_method=HMAC-SHA1","error_code":"401"}
{"request":"/search.json?q=?é????","error":"oauth_signature=XMJW2PnNi1TuL1kSkiwCmBbSejA= oauth_signature_base_string=GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0 oauth_problem=signature_invalid oauth_signature_method=HMAC-SHA1","error_code":"401"}

 at t4j.http.HttpClient.httpRequest(HttpClient.java:572)
    at t4j.http.HttpClient.httpRequest(HttpClient.java:572)
 [Wed Feb 16 21:15:25 CST 2011]Response:
[Wed Feb 16 21:15:25 CST 2011]Response: 
 [Wed Feb 16 21:15:25 CST 2011]HTTP/1.1 401 Unauthorized
[Wed Feb 16 21:15:25 CST 2011]HTTP/1.1 401 Unauthorized
 [Wed Feb 16 21:15:25 CST 2011]Content-Language:
[Wed Feb 16 21:15:25 CST 2011]Content-Language: 
 [Wed Feb 16 21:15:25 CST 2011]Date: Wed, 16 Feb 2011 13:15:33 GMT
[Wed Feb 16 21:15:25 CST 2011]Date: Wed, 16 Feb 2011 13:15:33 GMT
 [Wed Feb 16 21:15:25 CST 2011]Transfer-Encoding: chunked
[Wed Feb 16 21:15:25 CST 2011]Transfer-Encoding: chunked
 [Wed Feb 16 21:15:25 CST 2011]Expires: Thu, 01 Jan 1970 00:00:00 GMT
[Wed Feb 16 21:15:25 CST 2011]Expires: Thu, 01 Jan 1970 00:00:00 GMT
 [Wed Feb 16 21:15:25 CST 2011]Content-Type: application/json;charset=utf-8
[Wed Feb 16 21:15:25 CST 2011]Content-Type: application/json;charset=utf-8
 [Wed Feb 16 21:15:25 CST 2011]Connection: keep-alive
[Wed Feb 16 21:15:25 CST 2011]Connection: keep-alive
 [Wed Feb 16 21:15:25 CST 2011]Server: nginx
[Wed Feb 16 21:15:25 CST 2011]Server: nginx
 [Wed Feb 16 21:15:25 CST 2011]Pragma: no-cache
[Wed Feb 16 21:15:25 CST 2011]Pragma: no-cache
 [Wed Feb 16 21:15:25 CST 2011]Cache-Control: no-cache, no-store, max-age=0
[Wed Feb 16 21:15:25 CST 2011]Cache-Control: no-cache, no-store, max-age=0

 [Wed Feb 16 21:15:25 CST 2011]
[Wed Feb 16 21:15:25 CST 2011] {"request":"/search.json?q=?é????","error":"oauth_signature=XMJW2PnNi1TuL1kSkiwCmBbSejA= oauth_signature_base_string=GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0 oauth_problem=signature_invalid oauth_signature_method=HMAC-SHA1","error_code":"401"}
{"request":"/search.json?q=?é????","error":"oauth_signature=XMJW2PnNi1TuL1kSkiwCmBbSejA= oauth_signature_base_string=GET&http%3A%2F%2Fapi.t.163.com%2Fsearch.json&oauth_consumer_key%3DEJ0GpH9mtU584qtY%26oauth_nonce%3D1981498615%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1297862125%26oauth_token%3D3d5ec3c98e57d20c40c458bfe6999d66%26oauth_version%3D1.0 oauth_problem=signature_invalid oauth_signature_method=HMAC-SHA1","error_code":"401"}

 at t4j.http.HttpClient.httpRequest(HttpClient.java:514)
    at t4j.http.HttpClient.httpRequest(HttpClient.java:514)
 at t4j.http.HttpClient.get(HttpClient.java:497)
    at t4j.http.HttpClient.get(HttpClient.java:497)
 at t4j.TBlog.get(TBlog.java:949)
    at t4j.TBlog.get(TBlog.java:949)
 at t4j.TBlog.searchStatus(TBlog.java:773)
    at t4j.TBlog.searchStatus(TBlog.java:773)
 at _jsp._callback__jsp._jspService(_callback__jsp.java:46)
    at _jsp._callback__jsp._jspService(_callback__jsp.java:46)
 at com.caucho.jsp.JavaPage.service(JavaPage.java:61)
    at com.caucho.jsp.JavaPage.service(JavaPage.java:61)
 at com.caucho.jsp.Page.pageservice(Page.java:578)
    at com.caucho.jsp.Page.pageservice(Page.java:578)
 at com.caucho.server.dispatch.PageFilterChain.doFilter(PageFilterChain.java:195)
    at com.caucho.server.dispatch.PageFilterChain.doFilter(PageFilterChain.java:195)
 at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:187)
    at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:187)
 at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:265)
    at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:265)
 at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:273)
    at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:273)
 at com.caucho.server.port.TcpConnection.run(TcpConnection.java:682)
    at com.caucho.server.port.TcpConnection.run(TcpConnection.java:682)
 at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
    at com.caucho.util.ThreadPool$Item.runTasks(ThreadPool.java:743)
 at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
    at com.caucho.util.ThreadPool$Item.run(ThreadPool.java:662)
 at java.lang.Thread.run(Thread.java:662)
    at java.lang.Thread.run(Thread.java:662)

上面的提示是你的认证没通过,其实完全不是这么回事,你只要把那个搜索语句改一下就得了:
 List<Status> list = tblog.searchStatus(java.net.URLEncoder.encode("情人节","UTF-8"));
List<Status> list = tblog.searchStatus(java.net.URLEncoder.encode("情人节","UTF-8"));
到此,真的就都OK了,真的希望网易做事能彻底些,这些事其实如果有个好的例子,我也不用摸黑搞了两天。
完整的开发程序的地址在这里:http://dl.dbank.com/c035vpc4d4
我的微博 
http://t.sina.com.cn/1401900445