如何理解Rest服务


一种架构风格。


Rest(Representational State Transfer) 表述性状态转移
Rest 是一种架构风格,在rest架构风格中,对象被抽象为一种资源(resource)。
表述性状态是对资源数据在某个瞬间状态的快照,资源的某个瞬时状态被定义为一种表述。
请求一个资源==访问一个具有指定性和描述性的URI,经由http,将资源的表述从服务器转移到客户端。
REST: 指的是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。
RESTful:如果一个架构符合REST原则,就称它为RESTful架构。

面向资源的架构。


Rest式架构意味着,方法信息都在HTTP方法里,面向资源的架构(ROA)意味着,信息域消息都在URI里,二者结合起来是很强大的。一个面向资源的Rest式web服务,通过HTTP请求的一行数据,基本就知道客户端想做什么事情了。HTTP请求的其余部分只是细节而已。如果HTTP方法跟方法信息对不上,那么服务就算不上是Rest式的。如果作用域信息不放在URI里面,那么服务就不是面向资源的。


资源的表现层


那么什么是资源的表现层,大家一定看晕了,简单说,什么是资源,web服务就是我们经常说的网站,那么一个网站上的资源可以是一段文字,可以是一个图片,一段音乐,等等。这些资源有多种表现方式,这些表现方式就是资源的表现层,比如HTML,XML,PNG,JSON

状态转移(State Transfer)

对这个网站的访问就引发了客户端对服务器的一次请求,如果客户端想要操作服务器就需要通过一种手段去让服务器发生状态转移,而这种转换是通过资源表现出来的。这就是表现层状态转移。客户端使用HTTP来操作资源,http是一种无状态的协议,也就是说,当你第一次请求数据的时候,服务器给你数据,当你用同一个客户端再次请求数据的时候,它还会做重复的操作。协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。


HTTP动词


对于资源的具体操作类型,由HTTP动词表示。
常用的HTTP动词有下面五个(括号里是对应的sql命令)。
  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源。


综上什么是restful服务:

 (1)每一个URI代表一种资源;
 (2)客户端和服务器之间,传递这种资源的某种表现层;
 (3)客户端通过HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

代码实现


我们的项目前台是用angularjs,在前台使用的是$resourse定义Restful服务

1.先在index.html 中引入需要的js:

<script src="js/services.js"></script>
<!--使用Restful必须引入的脚本-->
<script src="lib/ionic/js/angular/angular-resource.js"></script>



2.自己写的服务:js/services.js


声明module,定义工厂服务

<span style="font-family:KaiTi_GB2312;">angular.module('itoo-exam-evaluation.services',['ngResource'])
 
.factory("userService",function($resource){
return $resource('http://localhost:8100/localhost/'+'login'+'/userCode/:userCode'+'/password/:password',{},{
        query:{method:'GET',params:{},isArray:false}
});
})</span>



3.把服务模块添加到app.js依赖的数组里面

angular.module('itoo-exam-evaluation',['ionic','itoo-exam-evaluation.controllers','itoo-exam-evaluation.routes','itoo-exam-evaluation.services','itoo-exam-evaluation.directives'])




数据地址:

.constant('studentWebUrl','http://localhost:8100/192.168.22.248/');//调试的时候使用的本地接口



4.Controller.js中传递服务的参数,在controller中调用服务(query)
.controller('userCtrl',function($scope,$ionicPopup,$state,userService)
  userService.query({userCode:userCode,password:password},function(data){
//判断返回结果是否为真
if(data.result==true){
if(data.allUsers.password==password){
/*如果用户名密码正确,将用户名密码写入localStorage中,跳转到今日课程页面*/
              localStorage.setItem("userCode",userCode);
              localStorage.setItem("password",password);
/*alert(localStorage.getItem("userCode"));*/
/*跳转到今日课程界面*/
              $state.go("evaluationTask");
}else{
                var alertPopup = $ionicPopup.alert({
                    title:'提示',template:'密码错误!',okType:'button-positive'
});
                alertPopup.then(function(res){
                  $scope.userInfo.password='';
});
 
}
}else{
            var alertPopup = $ionicPopup.alert({
                    title:'提示',template:'用户名错误!',okType:'button-positive'
});
                alertPopup.then(function(res){
                  $scope.userInfo.userCode='';
                  $scope.userInfo.password='';
});
}
},function(){});



5.后台登陆接口:

/*登陆接口*/
@ResponseBody
@RequestMapping(value="/login/userCode/{userCode}/password/{password}",method=RequestMethod.GET,produces ="text/html;charset=UTF-8")
publicString login(@PathVariable("userCode")String userCode,@PathVariable("password")String password){
System.out.println("用户名为:"+userCode);
System.out.println("密码为:"+password);
return"{\"result\":true,\"allUsers\":{\"id\":\"12EBA23Qsew345\",\"userName\":\"1\",\"userCode\":\"1\",\"password\":\"1\",\"headImage\":\"img/01.jpg\",\"roleType\":0}}";
}


RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。使用注解需要在ApplicationContext.xml中配置<context:component-scan base-package="itoo.exam"> 去扫描包中的注解。

也可以在JSP中写AJAX去请求数据:

$.ajax({
           url:'student/1/course/5',type:'DELETE',success:function(data){
                alert(data);
},error:function(data){
                alert("error");
}
})



总结


现在越来越多的公司倾向于采用面向服务(service-oriented)的架构,由后端提供给前端RESTful的接口,这么做是为了更好的做前后端的依赖分离。如果所有的关键业务逻辑都封装成REST调用,就意味着在上层只需要考虑如何用这些REST接口构建具体的应用。那些后端程序员们根本不操心具体数据是如何从一个页面传递到另一个页面的。当后端程序员提供了REST服务之后,不论后台用的是什么语言,都不会对前台造成影响的。

AngularJS3——使用$resourse定义Restful服务的更多相关文章

  1. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. ios – Objective-C中的Google用户serverAuthCode nil

    我正在尝试将GoogleSignIn框架集成到iOS应用程序中,并对服务器上的用户进行身份验证.我设法登录用户,但在–(void)signIn:(GIDSignIn*)signIndidSignInForUser:(GIDGoogleUser*)用户withError:(NSError*)错误委托方法,user.serverAuthCode为nil,我需要通过此服务器身份验证代码,嗯,验证服务器上

  3. ios – Xcode 9架构x86_64的未定义符号

    先谢谢你的帮助.解决方法陷入类似的问题.只需在此处发布,以防它可以帮助任何人.在我们的应用程序的Objective-c类B中使用来自框架的类AbcService.从Xcode8/Swift3升级到Xcode9/Swift4后,由于未定义的符号,它无法为发布配置构建存档链接期间此类的错误:奇怪的是,它可以存档调试配置,并在模拟器中运行.花了差不多1天才找出根本原因:框架中的Swift类AbcService缺少一个公共修饰符.

  4. 保护MY REST API仅用于MY IOS APP

    我在Laravel中设计一个RESTAPI,用于我的ios应用程序.目前我被困在以下几点:如何保护我的RESTAPI只允许访问我的ios应用程序?听起来我需要通过向我的IOSAPP授予一个私钥来将类似于HMAC方法的内容合并到我的IOSAPP代码中.当从iosapp中运行请求时,我传递带有私钥和其他数据的哈希,然后当在服务器上收到请求时,我通过重新计算哈希来检测请求是否来自应用程序内的用户.我不知道这是否安全&我会认为不是吗?

  5. ios – Xcode 7.1 PrototypeTools链接器错误(仅限模拟器)

    我正在尝试使用Xcode7.1在iOS模拟器中运行我的应用程序,但我收到链接器错误.这是错误:clang:错误:链接器命令失败,退出代码为1这似乎是一个新问题,因为我在升级到新的Xcode之前没有它.我在Google上搜索过,但是这个问题几乎没有相关主题.有趣的是,该应用程序在设备上运行良好.我已经尝试重置模拟器并再次清洁/建造,但两者都没有奏效.有没有其他人遇到过这个问题,你能提供什么建议吗?

  6. xcode – 这是什么意思:架构的未定义符号x86_64“_main”

    在Xcode上构建我的应用程序时,我不断收到错误:我的代码没有错误,错误是奇怪的错误,我做的任何事情都无法解决.我不认为该代码与问题相关,因为它在错误中未被引用.这是错误的屏幕截图.解决方法链接器无法在主swift入口点的链接过程中找到任何文件.这可能是由于文件在项目中根本不存在,或者它存在但尚未包含在编译或链接构建阶段.在Swift中,主要的快速入口点在主要的SWF模块中定义,或者在AppDel

  7. ios – 当架构设置为64位时,图像不显示

    任何线索?

  8. iOS,ld:framework没有找到适用于架构arm64的GoogleMaps

    Podfile看起来像这个Cocoapodsv1.0beta6):解决方法更新请检查您是否在架构中具有相同的构建设置,并仅构建活动体系结构中的目标键你的podfile应该是这样的在您启动ProjectTest目标之前结束项目目标,也是为什么添加继承!

  9. ios – Zbar SDK – 缺少必需的架构x86_64

    在最近的Xcode5.1中,我在构建应用程序时遇到了一个问题.编译失败,出现“未定义的架构x86_64符号”错误.我使用有效架构构建我的项目:armv7,armv7s和arm64.在切换到最新的环境(Xcode)后,我在同一个架构中重新构建了libzbar.a库(我已经根据在LinkerErrorinXcode-5处找到的解决方案)也许有人也有同样的问题,最后他解决了,请分享解决方案:)解决方法我

  10. ios – Appstore FailureNo架构在二进制文件中. Lipo未能检测到bundle可执行文件中的任何架构.“在SoftwareAssets / SoftwareAsset

    嗨,我刚刚尝试将我的应用程式上传到应用程式商店,但失败了.****解决方法嗨,我很高兴我找到了答案.问题实际上是在info.plist中的“Productname”.在我的第一个版本是不同的.

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部