JDeveloper 11g中利用RestLet开发RESTful服务

2:14 am in Oracle 融合中间件 by aronezhang

 

 

Oracle JDeveloper11g发布之后,Oracle的Guru们也纷纷在她们的Blog中发布各种应用和特性的介绍,这不Lucas Jellema在AMIS的blog中就介绍了使用JDeveloper 11g来开发基于Restlet的RESTFul服务。

我也照葫芦画瓢学习了一下,开始步入REST架构的学习大潮中。

 

随着JCP关于REST网络服务的规范标准JAX-RS: Java API for RESTful Web Services (JSR 311)最终版的尘埃落定,REST设计风格的Web服务应用也得到了进一步的应用与推广,很多流行的架构也宣称在未来的版本中将支持REST架构,如大名鼎鼎的Spring宣称在未来3.0版本中全面支持REST;同时很多Web服务开始采用REST风格设计和实现,例如Amazon,Google和Yahoo都提供了REST风格的Web查询服务。

 

本文就是将围绕Restlet来实现一个RESTFul的web服务

 

 

1,JDeveloper11g下创建一个项目

2,使用默认的配置创建一个JSP页面,将其命名为restful.jsp

3,添加库文件:下载Restlet压缩包,从lib目录中挑选com.noelios.restlet.ext.servlet_2.5.jar, com.noelios.restlet.jar, org.restlet.jar,将它们添加到刚创建的项目库和Classpath中

1.add_restlet_jar

 

4,创建Rest应用控制类

在Java包com.oracleseeker.rest.controller中创建RestApplication类,这个类用来设置各种资源和URI,开始设置一个资源(notes)和一个URL(/notes)映射到这个资源,类中也初始化Note对象。

因此后面进一步向类中添加路由限制来对资源的获取进行限制,路由通过模式匹配的方式来支持。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.oracleseeker.rest.controller;
 
import com.oracleseeker.rest.resources.Note;
import com.oracleseeker.rest.resources.NotesResource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.Router;
 
public class RestfulApplication extends Application {
 
    private Collection notes = new ArrayList();
 
    public RestfulApplication() {
        notes.add(new Note("appointment","Keyuan Road",new Date()));
        notes.add(new Note("conference","Zhangheng Road",new Date()));
        notes.add(new Note("training","Zhonghuan Road",new Date()));
    }
 
 
    @Override
    public Restlet createRoot() {
        Router router = new Router(getContext());
        router.attach("/notes", NotesResource.class);       
        return router;
    }
 
 
    public void setNotes(Collection notes) {
        this.notes = notes;
    }
 
    public Collection getNotes() {
        return notes;
    }
}

 

5,定义实体类Note

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.oracleseeker.rest.resources;
 
import java.util.Date;
 
public class Note {
    private String name;
    private String description;
    private Date creationDate;
 
    public Note() {
    }
 
    public Note(String name, String description, Date creationDate) {
        super();
        this.name = name;
        this.description = description;
        this.creationDate = creationDate;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }
 
    public Date getCreationDate() {
        return creationDate;
    }
}

 

6,定义资源类NoteResource

它用来提供REST架构中的资源,任何通过HTTP的请求要获得REST的资源最终都需要通过它来提供,而对资源的需要来自于上面定义的控制类

定义如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.oracleseeker.rest.resources;
 
import com.oracleseeker.rest.controller.RestfulApplication;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import org.restlet.Context;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.resource.DomRepresentation;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.restlet.resource.ResourceException;
import org.restlet.resource.Variant;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
 
public class NotesResource extends Resource {
    Collection notes;
 
    public NotesResource() {
    }
 
    public NotesResource(Context context, Request request, Response response){
        super(context, request, response);
 
        getVariants().add(new Variant(MediaType.TEXT_XML));       
        notes = getNotes();
    }
 
    private Collection getNotes() {
        return ((RestfulApplication)getApplication()).getNotes();
    }
 
    @Override
    public Representation represent(Variant variant) throws ResourceException {
        if (<font color="#000000">MediaType.TEXT_XML.equals(variant.getMediaType())</font>){
            try{
                DomRepresentation representation = new DomRepresentation(MediaType.TEXT_XML);
                Document doc = representation.getDocument();
                Element root = doc.createElement(&quot;notes&quot;);
                doc.appendChild(root);
 
                for(Note note: notes){
                    Element eltNote = doc.createElement(&quot;note&quot;);
 
                    Element eltName = doc.createElement(&quot;name&quot;);
                    eltName.appendChild(doc.createTextNode(note.getName()));
                    eltNote.appendChild(eltName);
 
                    Element eltDescription = doc.createElement(&quot;description&quot;);
                    eltDescription.appendChild(doc.createTextNode(note.getDescription()));
                    eltNote.appendChild(eltDescription);
 
                    Element eltCreationDate = doc.createElement(&quot;creationDate&quot;);
                    eltCreationDate.appendChild(doc.createTextNode(new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss&quot;).format(note.getCreationDate())));
                    eltNote.appendChild(eltCreationDate);
                    root.appendChild(eltNote);
                }
                doc.normalizeDocument();
                return representation;
            }catch (IOException e){
                e.printStackTrace();
            }
        } 
        return null;
    }
}

 

这个类继承了org.restlet.resource.Resource类,类的构造函数中指定了只支持TEXT_XML表现形式,然后类中重载了represent方法,这个方法是用来处理GET请求的,还有其它的方法用来处理POST,PUT,DELETE。方法创建了以notes为根元素note为子元素的XML文档,XML文档中的内容来自于RestfulApplication中的notes收集器

 

7,配置web.xml文件

为了保证所有访问Restful资源的请求都能够被RestLet Servlet处理,需要创建URL模式(*)来匹配所有的请求。

添加如下的配置信息到web.xml文件中

 

1
2
3
4
5
6
7
8
9
10
  org.restlet.application
  com.oracleseeker.rest.controller.RestfulApplication 
 
 
  RestletServlet  
  com.noelios.restlet.ext.servlet.ServerServlet 
 
 
  RestletServlet  
  *

 

8,发布RESTFul服务,运行restful.jsp页面

 

运行restful.jsp页面,JDeveloper会将web服务发布到内置的Weblogic服务器,由于我们在web.xml中定义了所有的请求都通过RestLet Servlet来处理,因此运行的jsp页面报错。

只要修改浏览器中的URL地址,将restful.jsp修改为notes,修改为REST样式的URL,输出的结果如下:

2.restlet_xml_output

 

 

9,添加Note资源访问的限制

 

上面输出的是所有的Note资源,我们希望只是将某个Note的资源展现出来,因此需要对上面的控制类和提供资源的类进行修改,使它能够通过URL提供特定的Note资源: host:port/application/notes/{noteName}

REST资源URL的定位路由是由控制类来负责,因此需要将控制类RestfulApplication中的

router.attach("/notes}", NotesResource.class); 

修改为

router.attach("/notes/{noteName}", NotesResource.class);

 

而原来我们的资源类NotesResource返回的是所有的Note资源信息,因此需要添加根据控制类传递过来的参数进行资源的过滤,将资源提供类修改为如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class NotesResource extends Resource {
    Collection notes;
    Note note;
 
    public NotesResource() {
    }
 
    public NotesResource(Context context, Request request, Response response) {
        super(context, request, response);
 
        getVariants().add(new Variant(MediaType.TEXT_XML));
        notes = getNotes();
 
        String noteName = (String)getRequest().getAttributes().get(&quot;noteName&quot;);
        // Get the items directly from the &quot;persistence layer&quot;.
        note = getTheNote(noteName);
    }
 
    private Collection getNotes() {
        return ((RestfulApplication)getApplication()).getNotes();
    }
 
    @Override
    public Representation represent(Variant variant) throws ResourceException {
        if (MediaType.TEXT_XML.equals(variant.getMediaType())) {
            try {
                DomRepresentation representation =
                    new DomRepresentation(MediaType.TEXT_XML);
                Document doc = representation.getDocument();
                Element root = doc.createElement(&quot;notes&quot;);
                doc.appendChild(root);
 
                    Element eltNote = doc.createElement(&quot;note&quot;);
 
                    Element eltName = doc.createElement(&quot;name&quot;);
                    eltName.appendChild(doc.createTextNode(note.getName()));
                    eltNote.appendChild(eltName);
 
                    Element eltDescription = doc.createElement(&quot;description&quot;);
                    eltDescription.appendChild(doc.createTextNode(note.getDescription()));
                    eltNote.appendChild(eltDescription);
 
                    Element eltCreationDate =
                        doc.createElement(&quot;creationDate&quot;);
                    eltCreationDate.appendChild(doc.createTextNode(new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss&quot;).format(note.getCreationDate())));
                    eltNote.appendChild(eltCreationDate);
                    root.appendChild(eltNote);
                doc.normalizeDocument();
                return representation;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
 
    private Note getTheNote(String noteName) {
        Collection notes =
            ((RestfulApplication)getApplication()).getNotes();
        for (Note note : notes) {
            if (noteName.equalsIgnoreCase(note.getName()))
                return note;
        }
        return null;
    }
}

 

指定Note名称来得到相应的资源(/notes/conference)

3.special_xml

 

 

参考资料和链接

下载本文的JDeveloper 11g应用: Download JDeveloper 11g中利用RestLet开发RESTful服务 Version 1

 

Restlet

http://www.restlet.org/

First Steps with RestLet 1.1RC2 in JDeveloper 11g – restful services 101 by Lucas Jellema

http://technology.amis.nl/blog/3587/first-steps-with-restlet-11rc2-in-jdeveloper-11g-restful-services-101

 

目前主要几个支持REST的java架构:

Restlet(http://www.restlet.org/)

Cetia4(https://cetia4.dev.java.net/)

Apache Axis2(http://http://ws.apache.org/axis2/

sqlREST(http://sqlrest.sourceforge.net/)

REST-art(http://rest-art.sourceforge.net/

 

 

-

相关文章:

  1. REST 初识
  2. 扩展RestLet应用来创建和更新资源
  3. 通过ADF Data Control 发布RESTFul 服务的资源
  4. MyEclipse7下安装插件
  5. actionscript3中的动态类(dynamic class)
  6. 为Backingbean创建基类