利用GAE+RestEasy搭建webservice--编码与发布

 

利用GAE构建第一个REST风格的java webservice

1. 配置好你的Eclipse GAE开发环境

2. 测试一下你的GAE环境的配置是否正确。写个HelloWorld发布一下试试。

3. 让我们开始

? 利用GAE建一个gaeRest项目.记得把use google web toolkit勾去

clip_image001

项目如下

clip_image002

注意,droidinvokeRest是客户端调用的例子,现在先不管。下载RestEasy 框架http://sourceforge.net/projects/resteasy/files/Resteasy%20JAX-RS/注意,2.2.2.GA该版本在使用过程时会出现java.lang.IllegalAccessException: Reflection is not allowed on protected final java.lang.Class 错误。我使用了2.0.0.GA,虽然版本比较老,但是无论是本地发布还是正式发布都没有问题。为此问题,我也纠结了许久。最终在google app engine 官方开发论坛上找到答案。下载后,将里边的所有jar包拷贝到当前项目的war\web-inf\lib文件中(记得不这样做,会运行会报错。。),然后创建userlibray,链接到该lib路径,添加这些包的引用。?  创建数据实体,Book类,同时使用jaxb 注解,以用于对象序列化为 xml。关于jaxb你可以在网上找到相关资料。代码如下 

1   package   henu . cjt . webservice;
2  
3   import   javax . xml . bind . annotation . XmlElement;
4   import   javax . xml . bind . annotation . XmlRootElement;
5  
6   @XmlRootElement(name   =   " book " )
7   public   class   Book   {
8        private   String   name;
9        private   String   content;
10 
11       public   Book()   {
12       }
13 
14       public   Book(String   name,   String   content)   {
15            this . name   =   name;
16            this . content   =   content;
17       }
18 
19       @XmlElement
20       public   String   getName()   {
21            return   name;
22       }
23 
24       public   void   setName(String   name)   {
25            this . name   =   name;
26       }
27 
28       @XmlElement
29       public   String   getContent()   {
30            return   content;
31       }
32 
33       public   void   setContent(String   content)   {
34            this . content   =   content;
35       }
36  }
37

 ?  创建服务类Library,里边用来处理客户端的请求。使用@Path标注来标识资源路径。请求该路径时就会执行该方法。代码如下 

1   package   henu . cjt . webservice;
2  
3   import   javax . ws . rs . * ;
4   import   java . util . * ;
5   import   javax . ws . rs . core . * ;
6  
7   @Path( " /library " )
8   public   class   Library   {
9  
10       /* *
11         *   利用books来模拟数据存储区
12         *   在构造函数中添加数据
13         */
14       public   static   List < Book >   books   =   new   ArrayList < Book > ();
15       static   {
16            books . add( new   Book( " huhu " ,   " huhu " ));
17            books . add( new   Book( " haha " ,   " haha " ));
18       }
19 
20       /* *
21         *   获得所有的book列表
22         *   @return
23         */
24       @GET
25       @Produces( { MediaType . APPLICATION_ATOM_XML,   MediaType . APPLICATION_JSON   } ) // 设定返回的数据类型   xml   格式和json格式
26       @Path( " /books " )   // 资源的相对路径
27       public   List < Book >   listBooks()   {
28            return   books;
29       }
30 
31       /* *
32         *   获得指定id的书籍信息
33         *   @param   id
34         *   @return
35         */
36      
37       @GET
38       @Produces( { MediaType . APPLICATION_XML,MediaType . APPLICATION_JSON   } )
39       @Path( " /book/{id} " )
40       public   Book   getBook(@PathParam( " id " )   String   id)   {   // 将传入的id赋值给di
41            if   ( " 1 " . equals(id))
42                 return   new   Book( " huhu " ,   " huhu " );
43            else
44                 return   new   Book( " haha " ,   " haha " );
45       }
46 
47       /* *
48         *   利用put提交方式进行数据更新
49         *   @param   book
50         */
51       @PUT
52       @Path( " /book/{name} " )
53       public   void   updateBook(@PathParam( " name " )   PathSegment   book)   {
54            Iterator < Book >   it   =   books . iterator();
55            String   name   =   String . valueOf(book . getMatrixParameters() . get( " name " ));
56            String   content   =   String . valueOf(book . getMatrixParameters() . get(
57                      " content " ));
58            while   (it . hasNext())   {
59                 Book   booktmp   =   it . next();
60                 if   (name . equals(booktmp . getName()))   {
61                      booktmp . setContent(content);
62                      break ;
63                 }
64            }
65       }
66 
67       /* *
68         *   利用post方式进行数据增加
69         *   @param   name
70         *   @param   content
71         */
72       @POST
73       @Path( " /book/{name}/{content} " )
74       public   void   addBook(@PathParam( " name " )   String   name,
75                 @PathParam( " name " )   String   content)   {
76            books . add( new   Book(name,   content));
77       }
78      
79       @DELETE
80       @Path( " /book/{name} " )
81       public   void   deleteBookByName(@PathParam( " name " )   String   name) {
82            Iterator < Book >   iterator = books . iterator();
83            while (iterator . hasNext()) {
84                 Book   book = iterator . next();
85                 if (name . equals(name)) {
86                      iterator . remove();
87                 }
88            }
89       }
90  }
91

 ?  创建Application,类名 EasyRestApplication告知有哪些应用。继承与javax.ws.rs.core.Application代码如下 

1   package   henu . cjt . webservice;
2  
3   import   java . util . * ;
4   import   javax . ws . rs . core . Application;
5   import   org . jboss . resteasy . plugins . server . servlet . ResteasyBootstrap;
6  
7   public   class   EasyRestApplication   extends   Application   {
8  
9        HashSet < Object >   singletons   =   new   HashSet < Object > ();
10 
11       public   EasyRestApplication()   {
12            singletons . add( new   Library());
13       }
14 
15       @Override
16       public   Set < Class &lt; ? > &gt;   getClasses()   {
17            HashSet < Class &lt; ? > &gt;   set   =   new   HashSet < Class &lt; ? > &gt; ();
18            //   set.add(Library.class);
19            return   set;
20       }
21 
22       @Override
23       public   Set < Object >   getSingletons()   {
24            return   singletons;
25       }
26  }
27

 ?  接下来还要配置war文件夹中的web.xml添加配置如下 

1        < display-name > gaerest < /display-name >
2        < context-param >
3             < param-name > javax.ws.rs.Application < /param-name >
4             < param-value > henu.cjt.webservice.EasyRestApplication < /param-value >
5        < /context-param >
6        < context-param >
7             < param-name > resteasy.servlet.mapping.prefix < /param-name >
8             < param-value > /gaerest < /param-value >
9        < /context-param >
10       < listener >
11            < listener-class > org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap < /listener-class >
12       < /listener >
13       < servlet >
14            < servlet-name > GaeRest < /servlet-name >
15            < servlet-class > org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher < /servlet-class >
16       < /servlet >
17       < servlet-mapping >
18            < servlet-name > GaeRest < /servlet-name >
19            < url-pattern > /gaerest/* < /url-pattern >
20       < /servlet-mapping >

 上述工作完成后,就可以点击运行了。然后在浏览器中输入地址(如果你使用代理上网,你可能接受不到数据。。把代理去掉。)http://localhost:8888/gaerest/library/books你可以接受到如下内容 

< ?xml  version = " 1.0 "  encoding = " UTF-8 "  standalone = " yes " ? > < collection > < book > < content > huhu < /content > < name > huhu < /name > < /book > < book > < content > haha < /content > < name > haha < /name > < /book > < /collection >

  

本地发布成功。

微笑正式发布

https://appengine.google.com/登录后,创建相应的应用后。 然后点击Eclipse中的GAE发布按钮

clip_image003

如果没有登录google 账户,会提示你登陆接下来填写project名字时候,记得填写名字需要是你在google上创建的应用的名字。

而且该改名字你需要配置在 appengine-web-xml中, <application>cjtmobiles</application>。虽然,这一点已经超出了本文章的讲述范围,但是我还是愿意你能够顺利的发布。

发布成功后,你可以访问http://cjtmobiles.appspot.com/gaerest/library/books ,当然,cjtmobiles是我创建的应用的名字,记得改成你的。查看结果。

如果出现500内部server错误,你可以通过点击查看相应的日志

clip_image005

如果出现如下错误Caused by: java.lang.IllegalAccessException: Reflection is not allowed on protected final java.lang.Class java.lang.ClassLoader.findLoadedClass(java.lang.String)那么就是上边我说的RestEasy版本的问题,其实是其中jaxb的版本问题。我用jaxb 2.1.12也就是resteasy2.0.0 解决了这个问题。访问http://cjtmobiles.appspot.com/gaerest/library/books 成功返回相应数据后,恭喜你,你的服务端模型算是完成了

你也可使用cURL简单测试restful web service来使用各种提交方式,进行测试。

接下来,我们可以写一个简单的android客户端,模拟调用。



本文转自HDDevTeam 51CTO博客,原文链接:http://blog.51cto.com/hddev/662621,如需转载请自行联系原作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值