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中
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("notes"); doc.appendChild(root); for(Note note: notes){ Element eltNote = doc.createElement("note"); Element eltName = doc.createElement("name"); eltName.appendChild(doc.createTextNode(note.getName())); eltNote.appendChild(eltName); Element eltDescription = doc.createElement("description"); eltDescription.appendChild(doc.createTextNode(note.getDescription())); eltNote.appendChild(eltDescription); Element eltCreationDate = doc.createElement("creationDate"); eltCreationDate.appendChild(doc.createTextNode(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").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,输出的结果如下:
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("noteName"); // Get the items directly from the "persistence layer". 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("notes"); doc.appendChild(root); Element eltNote = doc.createElement("note"); Element eltName = doc.createElement("name"); eltName.appendChild(doc.createTextNode(note.getName())); eltNote.appendChild(eltName); Element eltDescription = doc.createElement("description"); eltDescription.appendChild(doc.createTextNode(note.getDescription())); eltNote.appendChild(eltDescription); Element eltCreationDate = doc.createElement("creationDate"); eltCreationDate.appendChild(doc.createTextNode(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").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)
参考资料和链接
Restlet
First Steps with RestLet 1.1RC2 in JDeveloper 11g – restful services 101 by Lucas Jellema
目前主要几个支持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/)
-
相关文章:
