无脚本JSP技术

为了让网页设计人员不需要学习JAVA而便捷的开发jsp,以及JSP中若引入java会导致难以维护(因为代码会给人感觉很乱),所以jsp中一般不使用JAVA脚本。为了代替JAVA代码,主要是使用JSP标准动作、表达式语言EL和标记JSTL。<!--more-->

标准动作

<jsp:useBean>申明和初始化一个bean

Example:

<jsp:useBean id=”person” class=”foo.Person” scope=”request”/>

Id:bean对象的标识符,即这个对象的名字。

Class:对象的类型。

Scope:对象的属性作用域,即这个对象是从哪个作用域得到的。默认为page。

Type:在建立多台bean时使用。

<jsp:getProperty>:获得bean性质的值

Example: <jsp:getProperty name=”person” property=”name”/>

Name:bean对象标识符,与<jsp:useBean>中id匹配。

Property:对象中的属性名。

注意,<jsp:useBean>如果找不到一个名为person的属性对象,他就会创建一个,并把这个对象设置到相应的作用域上面。

在创建属性对象person时,如果需要设置一些属性,可以使用<jsp:setProperty>。

但是,为了设置属性的动作只在创建一个新的对象时使用,<jsp:setProperty>可以放在<jsp:useBean>的体内,如下:

<jsp:useBean id=”person” class=”foo.Person” scope=”request”>

? ? ? ? ?<jsp:setProperty name=”person” property=”name” value=”Yang”>

? ? ? ? ?</jsp:useBean>

什么叫JavaBean,以下是JavaBean的基本法则:

  • 有一个无参数的公共构造函数
  • 按照约定命名公共的获取和设置方法。如getFoo()和setFoo()。
  • 设置方法和获取方法的参数需要相同。如int getFoo()和void setFoo(int foo)。
  • 性质的名和类型和获取方法和设置方法对应,而和类中的成员变量没有关系。如class中可以没有int foo的成员变量。
  • 结合JSP使用时,性质类型必须是String或者基本类型。

 

除了<jsp:include>动作外,常用的标准动作还有<jsp:include>,可以引入可重用的模版部件。除了这个标准动作,include指令也可以完成这个功能,不过他们俩内部原理并不相同。如对于插入“head.jsp”来说,Include指令在转换时插入head.jsp的源代码,就相当于把head.jsp的代码复制黏贴到该处。而对于<jsp:include>是在运行时插入head.jsp的响应。

对于<jsp:include>来说,运行时会带来额外的开销。而使用include指令只有在第一个请求时在将jsp文件转换成.class文件时才有开销。从这个角度来说,似乎可以只是用include指令而不是用<jsp:include>动作,但是当我们需要定制包含的内容时,比如我们要告诉head.jsp一些变量来定制我们要得到的内容,就需要使用标准动作来传入变量(<jsp:param>)。

表达式语言EL

在一些更加复杂的场合,如性质不是String或基本类型,而是数组等。此时无法使用JSP动作实现功能,可以使用表达式语言EL。

使用EL语言可以访问不同访问域中的变量,也可以使用EL隐式对象(和JSP隐式对象大体相同)访问一些参数,还可以使用EL函数通过一些配置调用类中的静态函数。

具体的使用方法本文中不再详述。

JSTL

 

Published: 13 Aug 2012

JSP基础

JSP生命周期

JSP最终都变成一个servlet来处理用户请求。

  1. 容器开始运行时,读取应用的DD,但此时不对jsp文件做任何处理
  2. 当jsp接收到第一个用户请求时,容器尝试将jsp转换为一个servlet类的源代码(myjsp_jsp.java)
  3. 容器将.Java文件编译为.class文件
  4. 容器加载新生成的servlet类
  5. 容器实例化这个servlet,并运行jspInit()方法,此时jsp作为一个servlet准备接收客户请求
  6. 容器创建一个新线程处理这个客户的请求,此过程中会调用_jspService函数。
  7. 在以后的客户请求中,只需要重复第7步。

JSP元素

1 脚本

使用<% %>,可在里面直接插入java代码

2 指令

使用<%@ %>,存在三种指令:

Page指令(常用)

定义页面特定的属性,如字符编码、页面响应的内容类型等。

存在多种属性,常用的有import:定义java import语句,增加到生成的servlet类中

Taglib指令

定义JSP可以使用的标记库。

Include指令(常用)

定义在转换时增加到当前页面的文本和代码,可更好的重用代码.

3 表达式

<%=?? %>,直接输出变量,和out.println()功能一样。

4声明

<%! %>, 声明中的内容作为对应的servlet的成员函数和成员变量。因为servlet很少使用或不应该使用成员变量,此声明大部分用于覆盖对应servlet的成员函数。

5EL表达式

6动作

JSP与servlet的对应关系

由上可知,jsp最后都会转换为servlet来处理用户请求,那jsp中的元素分别对应servlet里面的何种结构呢。

JSP生成的servlet实现了HttpJspPage接口。此接口存在三个关键函数,jspInit()函数在servlet的init()方法中调用,可以覆盖。jspDestroy()在servlet的destroy()函数中调用,可被覆盖。_jspService在servlet的service()函数中调用,不可以被覆盖。Jsp中的大部分代码会背放置在这个函数中。

Jsp中所有的html、java脚本以及表达式等都直接放置在servlet中的服务方法_jspService()函数中。Html和表达式通过out.write(“html代码或表达式”)输出。

<%@ page import=”” %>作为import…直接在servlet最顶端。

<%! %>声明中的内容直接放置在类中,在服务方法之外,作为servlet的成员变量和成员函数。此外,通过声明可覆盖HttpJspPage接口中的jspInit()函数和jspDestroy()函数。声明中的内容无论放在什么位置都作为servlet服务函数之外的内容,也就是说在jsp中可以使用代码放在声明代码之前,如:

<%=++count %>

<%!int count=0; %>

JSP和servlet一样,可以使用初始化参数和进行初始化。设置初始化参数使用<jsp-file>标签,表示这个servlet的配置对应这个JSP生成的servlet。初始化就可以通过覆盖jspInit()函数来实现。

除此之外,服务方法最前面有一堆隐式对象的声明和赋值,这些隐式对象可被直接使用。

API

隐式对象

JspWriter

Out

HttpServletRequest

Request

HttpServletResponse

Response

HttpSession

Session

ServletContext

Application

ServletConfig

Config

JspException

Exception

PageContext

pageContext

Object

page

注:pageContext里面封装了其他的隐式对象。

Published: 22 Jul 2012

会话管理和cookie

在Web应用中,由于HTTP协议是无状态链接,即每一次请求对Web应用来说都无法获知与该客户以前的历史信息,而Web应用往往需要使用会话信息。

会话信息往往是上一节所说的会话属性,可以将某些变量设置在session对象里。

会话实现方法

在某客户的一次请求中,如果Web应用对于该用户第一次希望为该客户建立会话以保存以后需要使用的信息,则容器生成一个会话ID,并通过响应把ID返回给客户;客户在以后的每一次请求中都同时发回这个会话ID。容器看到这个ID后,就根据这个ID找到匹配的会话。

在客户端和服务器交换会话ID信息是,最常用的方式是通过cookie交换ID信息。对于用户会话ID交换的cookie工作,容器可以完全自己实现而对编程人员透明。

使用HttpSession session=request.getSession();?? (1)创建一个新的session对象或者根据已存在的会话ID找到相应的Sesssion对象。

当在servlet使用语句(1)创建session对象时,容器就会自动的建立一个新的HttpSession对象,生成唯一的会话ID,创建新的cookie对象,将会话ID与cookie以及session对象相关联,并在响应中设置cookie。以上一切都是容器自动完成的。总之,使用语句(1)容器就会返回一个可直接使用session对象,其他编程人员无需关注(不代表可以不理解这些过程)。

URL重写

虽然大多数浏览器都支持cookie,但是如果万一不支持cookie的话,容器也可以使用URL重写来实现会话管理。

URL重写的概念就是在动态生成页面的时候将会话ID添加到所有的URL后面,这样就可以作为一个参数在用户的下次请求中被服务器获得。

一般容器在第一次为用户创建session对象时,同时使用cookie和URL重写,如果容器发现客户端支持cookie,在以后的交互中就不再使用URL重写了。

注:容器创建会话并不是在用户第一次请求的时候,而是在用户第一次请求需要使用会话的时候。即用户的请求的servlet中调用了request.getSession();

 

删除会话

当用户离开时,会话对象仍占用内存,而容器无法知道用户是否离去。因此容器一般根据超时撤销会话对象。也可以调用绘画对象的invalidate()手动撤销。

超时的时间一般默认为20分钟,可以设置。

 

Cookie的其他作用

Cookie原先设计是为了支持会话状态,但是也可以用其完成其他工作。默认的,cookie寿命和会话寿命一样,当客户离开浏览器时,cookie就会消失。支持会话ID的cookie就是这样子的。

但是cookie作为键值队可以保存在本地,即使浏览器关闭也不撤销并保存一段时间。当用户下次访问网站时,同时将这些cookie发送给服务器。比如网站上的下次自动登录就是这样实现的。

使用的例子如下:

//服务器端设置cookie返回给客户端

Cookie cookie=new Cookie(“username”,name);//创建cookie

cookie.setMaxAge(30*60);//设置cookie在客户端生存多久。单位:秒

response.addCookie(cookie);//将cookie设置在响应对象里以返回给客户端。

//当客户端提出一个请求并将保存的cookie顺便发送给服务器

Cookie[] cookies=request.getCookies();

for(int i=0;i<cookies.length;i++)

{

Cookie cookie=cookies[i];

If(cookie.getName.equals(“username”)){

String username= cookie.getValue();

break;

}

}

Published: 02 Jul 2012

SevletContext、SevletConfig参数和属性

SevletContext vs. SevletConfig参数

使用原因:将一些Web应用参数设置在部署文件web.xml中,以后如果需要修改只需要修改部署文件而不需要修改源代码。

生命周期

在Web应用启动servlet初始化时,容器会读取部署文件,并根据部署文件创建sevletConfig和SevletContent,并将读到的参数创建名/值对,同时向sevletConfig和SevletContent提供这些名/值对的引用。

完成以上步骤后容器创建servlet类的实例并在init方法中传入servletConfig引用。而所有的servlet和JSP都可以访问同一servletContext。

由上可知,初始化参数只会读一次,即容器初始化servlet的时候,或者说容器新启动的时候。所以在容器运行过程中,修改部署文件无法修改Web应用,只有重启才行。(也存在热部署方法)

区别:

? 每一个servlet一个ServletConfig而每个Web应用一个ServletContext。

? ServletConfig只能背自己的servlet访问,servlet也只能访问自己的ServletConfig;而应用中所有的servlet和JSP都可以访问ServletContext。

? 部署文件配置代码不同

? Servlet访问代码不同。

属性

属性就是一个对象,设置到ServletContext、HttpSession或HttpServletRequest上。

属性存在三种作用域,上下文、会话和请求。

上下文:

? 该作用域中属性在Web应用启动时就存在,直至应用结束。

? Web应用的所有部分都可以访问,包括servlet、JSP,linstener等等。

? 它不是线程安全的。

会话:

? 会话的生命周期从某一用户第一次开始访问Web应用开始,可以通过编程撤销,也可以通过超时自动撤销。

? 每一个会话涉及多个请求,比如用户先查看物品、然后购买物品。这些请求共享相同的会话属性。

? 他也不是线程安全的。因为同一用户可能同时发起多个请求。

请求:

? 请求的生命周期持续到servlet的service方法结束。

? 某一请求相应的servlet和JSP。

? 对于某个请求,如果应用从一个servlet开始,最后以一个JSP视图结束。Servlet和JSP通信时即使用请求属性,并使用RequesDispatcher。

 

Published: 27 Jun 2012

Servlet详解

Servlet任务就是得到客户的一个请求,根据请求执行任务并返回响应。

Servlet生命周期

Servlet的生命周期由容器来决定。

servlet生命周期只有一个状态——初始化。通常在容器启动时,容器找到servlet类文件,servlet生命周期开始。Servlet调用了构造 函数和init()函数之后,进入初始化状态。在这个状态中,它可以调用service()函数,在这个函数中根据请求调用doGet或doPost函数执行任务。

在容器中,每个Servlet只有一个对象,对于每个请求容器会运行一个线程来调用这个Servlet对象的函数。

对于init()函数我要多说一点,init函数用来初始化servlet,在调用servlet构造函数以后,生成了一个普通的对象,而调用了init函数以后,才成为一个真正的servlet,而且init函数在servlet一生中只运行一次。同时,在init函数里面我们可以放一些servlet的初始化代码,比如database连接代码等。那为什么不能将初始化代码放到servlet构造函数呢,这是因为servlet初始化往往需要ServletConfig对象(体现在web应用部署文件里面),而构造函数无法调用,这个和向前版本兼容有关[1],总之,记住,servlet构造函数不用写,所有的初始化的代码放到init函数里面!

请求和响应因为每个servlet只有一个实例,所以此Web应用的所有请求若访问这个servlet都是同一个实例,只是不同线程而已。所以,servlet的实例变量是所有的请求共享的,实例变量也不是线程安全的。一般来说,好的servlet一般不存在实例变量,或者就算存在也是final的。

请求和响应

Get和Post的区别上一节在HTTP角度已经有了一些说明,实践编程角度比较简单,本文就不介绍了。

首先来看请求对象,从请求对象里面我们可以得到什么?

最重要的,我们可以从请求对象里面获得客户传给我们的参数,如用户名、密码等。

除此之外,还可以获得浏览器信息、相关cookie及session信息等。

还有一些不常用的东东,比如请求HTTP方法、输入流等。

下面介绍响应对象。

对于响应对象,一般使用setContentType()函数设置内容类型,告诉浏览器内容是什么类型的以便浏览器处理。

然后,一般使用PrintWriter或OutputStream获得输出流,并将内容写入输出流即可。

完成以上步骤,刷新提交输出流即将输出流写入相响应象。

同时,我们可以使用一些函数设置响应首部信息。

除此之外,如果servlet不想自己处理响应,可以使用response.sendRedirect(strURL)函数,响应返回到浏览器后,浏览器会跳转到strURL。

我们还可以使用请求分派,在服务器端获得其他程序的帮助。一般为了不讲html代码写在servlet中,我们都在servlet运行完相关任务后使用请求分派将请求和相应对象使用请求分派传送给响应的jsp文件,根据jsp文件生成html文件返回给客户端。

Reference:

1 有关servletinit和构造函数??? http://feipigzi.iteye.com/blog/675798

Published: 25 Jun 2012

NP问题

预备知识

判断/最优问题

有些问题的答案只有两种,yes or no。对于这种问题,称为判断型问题。还有些问题目的是求出最优解,比如最短路径等,称为最优型问题。为了简化NP问题的讨论,我们将所有的问题都限定在判断型问题上。这种限定是科学的,因为所有的最优问题都可转化为判断问题。

Example:

一个优化型问题定义如下:给定一个有向图G(V, E)以及V中两顶点s和t,找出一条从s到t的简单路径使得它含有的边最多。

把上述优化问题定义为一个判断型问题

假设(a)中的判断型问题有多项式算法A,请用算法A为子程序,设计一个多项式算法来解决对应的优化问题。

(a)我们引入一个变量k后,这个判断型问题可定义如下:

给定一个正整数k和有向图G(V, E),以及V中两顶点s和t,是否存在一条含有至少k条边的从s到t的简单路径?

这个算法分两步,第一步确定最长的路径含有的边的个数k,第二步把这条最长路径找出来。做法是,对图中每一条边进行测试。如果把这条边刪去后,图中仍有一条长为k的路径,则将它刪去,否则保留。当每条边都测试后,剩下的边必定形成一条长为k的路径。

编码和语言

在计算机解决问题时,所有的问题都需要对问题进行编码表示。因此,对于一个判断性问题p,我们可以使用x表示其编码。

反之,给定一个子符串x,可以有三种情况:(1) x代表问题p的一个实例并且有答案yes;(2) x代表问题p的一个实例并且有答案no;(3) x不代表问题p的一个实例,只是一个杂乱的子符串而已。对第(1)种情况,我们用p(x) = 1表示,而用p(x) = 0表示另两种情况。

定义:给定一个判断型问题p,它对应的语言L(p) 是所有它的实例中有yes答案的实例的子符串编码的集合,即L(p) = {x | x ? S* and p(x) = 1}。

多项式归约

给定两个语言L1和L2,如果存在一个算法f,它把S*中每一个字符串x转换为另一个字符串f(x),并且满足

  • x ?L1 当且仅当f(x) ?L2,
  • f是个多项式算法,即转换在多项式时间内完成,

那么,我们说L1可多项式归约到L2,记为L1 p L2,f称为多项式转换函数或算法。

如图14-2所示,转换函数f把S*中每一个字符串映射到另一个字符串。注意,这个映射不要求单射(one to one),也不要求满射(onto),但一定要把L1 内的一个字符串映射到L2 内的一个字符,把L1 外的一个字符串映射到L2 外的一个字符串。

图1 多项式转换函数f必须分别L1 内和L1 外的字符串映射到L2 内和L2

P问题

P语言类(class P)是所有可以被一个算法在多项式时间内判定的语言的集合,即P = {L | L í S* 可被一多项式算法所判定}。如果语言L可以被一个算法在多项式时间内判定,那么L被称为属于P类的一个语言。

如果问题p对应的语言L(p)属于P类,那么问题p也称为P类问题。

P问题代表着这个问题可以被确定性图灵机在多项式内解决。

NP问题

NP问题是可以被非确定性图灵机在多项式时间内解决的问题。

非确定图灵机是一个理论模型,与确定性图灵机不同在于转换函数,确定性图灵机的转换函数是一对一的,而非确定性图灵机转换函数是一对多的。一个问题可以使用非确定型图灵机解决,我们可以将非确定性图灵机的状态路径树看作问题的遍历。

使用非确定性图灵机证明NP问题往往非常复杂,一般使用多项式检验机模型。

多项式检验机的输入除了问题的编码以外,还要求输入一个证书。证书是用来证明问题可以得到yes的回答。只要设计出了一个检验算法可以验证这个证书的正确性,那么这个问题就是NP问题。

例:证明判断有向图G(V, E)是否有哈密尔顿回路问题属于NP类。

证明:????如果G(V, E)有哈密尔顿回路,它通过每个顶点正好一次,那么我们可以把这个回路作为证书来验证。我们用p表示有n个顶点的序列并作为输入的证书。多项式检验算法的伪码如下:

Hamilton-Cycle-Verification (G(V, E), p)

  1. 检查是否有|p| = |V|
  2. 检查 p 中每个顶点是否属于集合 V
  3. 检查V中每个顶点是否在p中出现
  4. 检查从p中每个顶点到下个顶点是否是E中一条边
  5. 检查从p的最后一个顶点到p的第一个顶点是否是E中一条边
  6. 如果第1步到第5步的答案都是yes,那么输出1,否则输出0
  7. End

?这个模型和非确定性图灵机在本质上是相同的。因为在非确定性图灵机中,我们有很多状态路径,如果问题有一个解,那么这个问题就是NP问题。那么我们假设已经找到了这个解作为证书,那么我们就可以使用确定性图灵机来判断这个证书。

其实,我们在现实中遇到的问题几乎全部都是NP问题,非NP问题只在理论上存在,实践中除非复杂性计算方面的科研项目才可能遇到。所以,一般问题都是NP问题,证明只是为了更加严谨。

NPC问题

NPC问题是NP问题中最难的问题,所有的NP问题都可以多项式归约到NPC问题,而且NPC问题之间也可以互相归约。

目前为止,人们还不知道是否有一个NPC语言L可以被一多项式算法所判定,也不能证明任何一个NPC语言L不可能被一多项式算法所判定。因此,如图14-4所示,集合P,NP,和NPC的关系有两种,但大部分人相信第二种(图14-4(b)),但有待证明。

图2 集合P、NP、和NPC的两种可能的关系

NPC问题证明

根据NPC的定义,我们如果要证明一个问题是NPC,首先要证明这个问题是NP问题,然后证明所有的NP问题都可以归约到这个问题。

证明NP问题比较简单,但是证明所有的NP问题都可以归约这个问题相对比较复杂。但是,我们可以利用已知的NPC问题,因为所有的NP问题都可以归约到已知的NPC问题,如果已知的NPC问题可以归约到新的问题,那么新的问题也是NPC问题。

利用已知NPC问题证明新的问题是NPC问题的思想如下:

找到新问题对应的判定性问题,将已知的NPC通过某种变化变成新问题的某一特例,并保证已知NPC问题成立当当且仅当新问题成立。

将已知NPC问题变为新问题特例没有一个通用的方法,找到这种方法需要一些技巧,也需要一些经验甚至灵感。

Published: 12 Jun 2012

JSP&Servlet底层机制

 

网站工作机制

客户端与用户交互,用户通过客户端向服务器发送请求信息,Web服务器接收到客户的请求后查找资源,并将资源发挥给客户端。在这个过程,用到了两个比较重要的概念HTML标签语言和HTTP协议。

  • ?HTML:用标签来描述客户端应该显示给用户的界面。服务器对某一请求做出的回答一般是一个HTML页面,客户端获得后显示给用户。
  • ?HTTP:服务器和客户通信所使用的协议。主要分为:
    • ?HTTP请求
      • Get方法:简单的请求,不从客户端传送数据给服务器。(可以带一些参数,会直接显示在URL后面)
      • ?Post方法:可以请求某个资源,同时向服务器发送一些数据(如用户名、密码等)
      • Get和Post传递参数不同,Get直接在URL里面体现,而Post会在请求首部后面添加消息体(有效负载),用户无法从URL中看到。

    • <li>HTTP响应:包括响应首部和内容。首部包括一些响应的属性,如Content-type表示告诉浏览器要接受的数据是什么类型。</li>
      

总之,网站工作机制如下:

1)?????? 用户提交一个URL(或表单)

2)?????? 浏览器创建一个HTTP GET(或Post)请求

3)?????? HTTP请求发送给服务器

4)?????? 服务器找到相应资源

5)?????? 生成HTTP响应

6)?????? 发送给客户端(浏览器)

7)?????? 浏览器显示资源,一般是一个HTML页面

 

动态页面生成机制

以上是静态的网站,在动态网站中,主要不同时在第3步。服务器无法找到相应的资源,而是要去生成一个页面。这是我们就需要另一个应用,Web服务器与它交互生成页面返返回给客户端。

容器就是这么一个应用程序。当某个请求指向servlet而不是静态html页面,Web服务器把这个请求交给容易,容器调用servlet获得响应。

  • 使用容器管理和运行servlet减少了很多工作量,他提供一些功能。
  • 通信支持:让Web服务器和servlet对话。
  • 生命周期管理:初始化servlet、调用servlet及回收资源。
  • 多线程支持:某个servlet请求创建一个新的线程。
  • 声明方式实现安全:使用XML部署描述文件配置。
  • JSP支持。

 

容器处理请求的步骤:

1)?????? 容器收到请求

2)?????? 创建两个对象HttpServletResponse和HttpServletRequest

3)?????? 根据请求中的URL找到正确的servlet,为这个请求创建一个线程,并将请求和响应对象传递给这个线程。

4)?????? 容器调用servlet的service()方法,此方法根据请求类型调用doGet()或doPost()方法。

5)?????? 在doGet或doPost方法中生成动态页面,并将动态页面放入响应对象中。

6)?????? 容器将响应对象转换为HTTP响应,发送给Web服务器。

 

Published: 08 Jun 2012

新浪微博开放平台java-SDK使用的基本方法

  1. 创建一个应用,主要是为了获得App Key和Secret Key。具体说明请看官方文档:
    http://open.weibo.com/wiki/%E6%96%B0%E6%89%8B%E6%8C%87%E5%8D%97
  2. 下载新浪微薄的SDK,本文使用的是java。
    http://code.google.com/p/weibo4j/
  3. 请先填写相关配置:在Config.properties里
    client_ID :appkey 创建应用获取到的appkey (App Key) client_SERCRET :app_secret 创建应用获取到的appsecret (Secret Key) redirect_URI : 回调地址 OAuth2的回调地址 (这个是为了在验证后返回到我们的web地址,此篇文章只是为了测试,不创建web应用,因此可以不需要设置) 在调用/使用所有的api之前都需要进行Oath2验证。 关于OAUTH协议可以参考?http://oauth.net/2 使用OAUTH认证来获取微博数据介绍详细见:Oauth2 具体步骤: 调用example里:OAuth4Code.java。 会出现以下错误,是因为我们没有设置回调地址,没关系,复制code。 在myeclipse控制台里面黏贴进去,然后回车。 会显示以下结果: 这里可以看到我们得到了需要的access token。复制下来,以便下面调用其他API使用。
  4. 调用API
    经过Oath2验证以后就可以随意调用开放平台提供的各种API。 比如,我们调用获取粉丝,调用example.friendships.GetFlowers.java. [java] package weibo4j.examples.friendships; import weibo4j.Friendships; import weibo4j.Weibo; import weibo4j.examples.oauth2.Log; import weibo4j.model.User; import weibo4j.model.UserWapper; import weibo4j.model.WeiboException; public class GetFollowers { public static void main(String[] args) { String access_token = "2.00RkFknBuc4hPD05d15a59e6Yi3WRB(Access Token)"; Weibo weibo = new Weibo(); weibo.setToken(access_token); Friendships fm = new Friendships(); String screen_name ="任意用户的名字"; try { UserWapper users = fm.getFollowersByName(screen_name); for(User u : users.getUsers()){ Log.logInfo(u.toString()); } System.out.println(users.getNextCursor()); System.out.println(users.getPreviousCursor()); System.out.println(users.getTotalNumber()); } catch (WeiboException e) { e.printStackTrace(); } } } [/java] 运行之前设置access token 和用户名字,运行后: 注意: Example提供的都是控制它程序,也就是说都用运行main函数的demo,要运用到web程序需要响应的修改。 附: 使用Oath1验证(10年时的版本)的Web应用: http://haolloyin.blog.51cto.com/1177454/412445

Published: 10 Feb 2012