2024年10月restful风格增删改查案例(spring mvc restful风格的api怎么过滤相同路径)
⑴restful风格增删改查案例(springmvcrestful风格的api怎么过滤相同路径
⑵springmvcrestful风格的api怎么过滤相同路径
⑶Restful风格的API是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。在Restful风格中,用户请求的url使用同一个url而用请求方式:get,post,delete,put...等方式对请求的处理方法进行区分,这样可以在前后台分离式的开发中使得前端开发人员不会对请求的资源地址产生混淆和大量的检查方法名的麻烦,形成一个统一的接口。在Restful风格中,现有规定如下:GET(SELECT:从服务器查询,可以在服务器通过请求的参数区分查询的方式。POST(CREATE:在服务器新建一个资源,调用insert操作。PUT(UPDATE:在服务器更新资源,调用update操作。PATCH(UPDATE:在服务器更新资源(客户端提供改变的属性。(目前jdk未实现,tomca
⑷泛型方法,RESTful应用问题,怎么解决
⑸publicstatic《T》voidsynInfoForTable(Class《T》clazz,List《T》){}其中T是不能调用任何方法的,想要T的类型,只能传Class《T》clazz。那么这个T怎么用呢?你就把T认为是一个返回类型:比如在方法中List《T》tblInfoListFromDB=newLinkedList《T》(query.list());for(TtblInfoAPI:tblInfoListFromAPI){}就是对T的使用。下面例子是一个同步案例:/***将信息更新到数据库(同步**paramclazz*实体类对应的class*parampareField*从API获取的对象与数据库中的对象要比较的字段,首字母大写,只能比较字符串*paramprimaryKeyField*实体对象的主键字段,首字母大写*paramprimaryKeyClass*主键字段对应的class*paramtblInfoListFromAPI*从API获取的对象集合*throwsHcException*/publicstatic《T》voidsynInfoForTable(Class《T》clazz,StringpareField,StringprimaryKeyField,Class《?》primaryKeyClass,List《T》tblInfoListFromAPI,IntegercloudSign,String...userId)throwsException{Sessionsession=HBUtil.openNewSession();Transactiont=null;try{t=session.beginTransaction();StringBuilderhql=newStringBuilder(“from“);hql.append(clazz.getSimpleName());hql.append(“wherecloudIdISNOTNULLANDdeleted=:deletedANDcloudSign=:cloudSign“);if(userId.length》){//如果要根据用户同步,那么在查询时先查询出该用户的资源hql.append(“ANDuserId=:userId“);}Queryquery=session.createQuery(hql.toString());query.setInteger(“deleted“,);//只取未删除的query.setInteger(“cloudSign“,cloudSign);if(userId.length》){query.setString(“userId“,userId);}SuppressWarnings(“unchecked“)List《T》tblInfoListFromDB=newLinkedList《T》(query.list());MethodpareMethod=clazz.getMethod(“get“+pareField);MethodgetPrimaryKeyMethod=clazz.getMethod(“get“+primaryKeyField);MethodsetPrimaryKeyMethod=clazz.getMethod(“set“+primaryKeyField,primaryKeyClass);for(TtblInfoAPI:tblInfoListFromAPI){//使用增强循环booleanflag=true;StringpareAPI=(String)pareMethod.invoke(tblInfoAPI);for(TtblInfoDB:tblInfoListFromDB){StringpareDB=(String)pareMethod.invoke(tblInfoDB);if(pareAPI.equals(pareDB)){//db方后面的原因是可能为空if(!tblInfoAPI.equals(tblInfoDB)){//如果对象有变化,就要更新,否则不更新//为了防止主键被置为空,所以最后还要将原先的主键值保留下来,并赋值回去//这步如果之前已经赋值过,就没必要做了ObjectprimaryKeyValue=getPrimaryKeyMethod.invoke(tblInfoDB);CopyIgnoreProperty.copy(tblInfoAPI,tblInfoDB);if(getPrimaryKeyMethod.invoke(tblInfoDB)==null){setPrimaryKeyMethod.invoke(tblInfoDB,primaryKeyValue);}session.update(tblInfoDB);}//从集合中移除存在,是为了下面移除不存在的tblInfoListFromDB.remove(tblInfoDB);flag=false;break;}}if(flag){//true为api新增的//如果主键是String类型(不会自动增长的,且如果没有被赋值,那么就给他赋值//字符串,长度的if((getPrimaryKeyMethod.invoke(tblInfoAPI)==null)&&(primaryKeyClass==String.class)){setPrimaryKeyMethod.invoke(tblInfoAPI,UUIDHexUtil.generatebit());}session.save(tblInfoAPI);}}//因为前面tblVmInfoListFromDB已经把存在的都移除了,剩下的都是不存在了的for(TtblInfoDB:tblInfoListFromDB){session.delete(tblInfoDB);}//只要mit没有执行,就不会保存数据t.mit();}catch(Exceptione){if(t!=null){t.rollback();}thrownewException(“数据库同步异常:“+e.getMessage(),e);//调用者会说明是什么异常}finally{session.close();}
⑹ElasticSearch:http请求的使用方式(增删改查
⑺ElasticSea
⑻DELETE/my-index/_doc/
⑼GET/my-index/_doc/
⑽标准分词器汉字是一个字为一个词
⑾default_field:默认查询字段,query:查询条件(会先进行分词
⑿标准分词器英文按空格分词,中文按字分词
⒀c#调用restful风格的javaWebService例子
⒁restful那就是普通的get或者post请求了(该用post还是get取决于接口的设置,你百度搜索一下c#postget,第一个就是,至于java中取ip就是普通的网页上取ip的方法,即request.getRemoteAddr
⒂RESTfulAPI风格
⒃在进行API接口设计时,不同的开发人员可能有不同的设计风格,风格迥异。
⒄那是否存在一种统一的接口设计方式,被广大开发人员所接受呢?
⒅答:这就是被普遍采用的RESTfulAPI设计风格。
⒆路径又称“终点“(endpoint,表示API的具体网址,每个网址代表一种资源(resource。
⒇URL地址尽量使用名词,不使用动词。
⒈举例来说,以下是不好的例子:
⒉对于一个简洁结构,应该始终用名词。
⒊API中的名词应该使用复数,无论单个资源或者所有资源。
⒋举例来说,获取产品的API可以这样定义:
⒌访问同一个URL地址,采用不同的请求方式,代表要执行不同的操作。
⒍常用的HTTP请求方式有下面四个:
⒎过滤参数可以放在查询字符串中。
⒏在访问API接口获取数据时,可能需要对数据进行过滤。
⒐下面是一些常见的参数:
⒑针对不同操作,服务器向用户返回的响应数据应该符合以下规范:
⒒服务器返回的响应数据格式,应该尽量使用JSON。
⒓服务器向客户端返回的状态码和提示信息,常见的状态码如下:
⒔json-server增删改查排序小结
⒕json-server可以用于模拟请求----Restful风格查询get??params:{}增加post?data:{}删除delete修改put/patch?data:{}使用步骤-全局安装npmijson-server-g?/yarnglobaladdjson-server?相当于安装了一个命令行工具-准备json文件{“list“:}-在当前json文件下运行json-serverdata.json?开启本地服务开启服务-看到上图表示服务开启成功axios({method:“get“,url:“).then(res=》{this.list=res.data;}).catch(err=》{console.log(err);})-查询指定id的数据axios({method:“get“,url:“).then(res=》{this.list=res.data;}).catch(err=》{console.log(err);})-增加数据postaxios({method:“post“,url:“).then(res=》{this.getData()}).catch(err=》{console.log(err);})-删除指定id的数据axios({method:“delete“,url:`axios({method:“patch“,url:`举例:{id:,name:“zs“,age:}修改age=put:{id:,age:}patch:{id:,name:“zs“,age:}链接:
⒖vueadmin增删改查(五
⒗此篇幅比较长,涉及到的小知识点也比较多,一定要耐心看完,记住学东西没有耐心可不行!!!一、添加和修改注:添加和用到了同一个组件,也就是此篇文章你能学会如何封装组件及引用组件;第二能学会async和await;第三父向子传递数据props和子向父传递数据$emit();.添加数据(请求地址:/article/category利用post传递数据(编写api:注意add的url地址用的反单引号,可以在url后面进行组合数据,这个知识点在和删除你会看到详细的解释。(编写方法首先新建一个组件,里面的代码同样是从elementUI中复制过来的表单,下面会根据详细步骤解析elementUI标签中属性的意思。在category/index.vue中进行引用,注意组件要首字母大写,不是必须的,但是最好规范一些。引用完毕之后进行修改edit.vue组件:解析::title动态绑定的title名称;:visible.sync布尔类型,控制模态框的显示与否;:before-close是一个方法,关闭模态框;:rules表单验证;ref=相当于id=;:model表单的数据;prop=关闭模态框时清除数据要用到,这个在elementUI中有解释,自己去看文档;v-model绑定的具体数值;:label绑定的数据,要做默认选中效果;click执行的方法由于是父组件向子组件传递数据,所以在子组件中要用props进行接收,然后在上面进行动态绑定;注意:所有接受的变量要定义type和default,声明类型和默认值;此处小知识点,子组件向父组件传递值用$emit();表单验证:在子组件中返回rules,也就是开头:rules=“rules“;注意:这里的rules是个object,里面需要验证的字段是个array,数组中每个value都是object,详细的验证方法在elementUI中有体现,自己去看。此处定义的handleClose、onSubmit、submit方法;注意:在submit中有和添加方法,用的同一个,所以有if判断;this.$refs.resetFields()相当于jquey中$(’#form’).resetFields()清空数据;async、await和promise区别,自己去百度,这里只说明async和await是es新语法,相当于api.add(this.formData).then((res)=》{//TODO});这里可能有同学会有疑问,this.closeForm()这个方法在哪?他是父组件传递过来的Funciton,在下文中会解释到。开始操作父组件index.vue,在data中返回edit对象,然后把里面的值绑定到组件标签中;解析:title就是title;visible是否显示模态框;formData传递过去的数据,由于是添加功能,所以formData是空的,就需要传递了;closeForm传递一个方法,用来关闭模态框到这里,添加功能就已经实现了,仔细去看我上面的截图,一定要注意我说的点,如果你比着写发现不对,一定要仔细对比。当对比不出来的时候,留言告诉我。.修改数据(请求地址:/article/category/{id}查询数据用get,这里的请求类型用的是restful请求方式,restful包含:get、post、put、patch、delete;/article/category修改数据用put(编写api:由于修改需要先查到数据,然后再进行传递和渲染,所以在api中有一个查询数据方法,也就是getById()(编写方法在index.vue父组件中方法为handleEdit(),同样这里用到了async和await,然后先请求到了当前id返回的值,然后传递到edit.vue子组件中。这里的if判断,判断传递过来的formData的id值是否为空,有值说明是,无值说明是添加。if判断就在这里进行的体现价值,因为我们添加和用的同一个组件,所以if显得至关重要。仔细去看代码,去理解我的思路,为什么某些地方是这样写而不是那样写,一定要注意。哪里有看不明白的一定要留言进行讨论,我看到会第一时间回复。最终的效果:二、删除(请求地址:/article/category/{id}删除用的是delete请求类型(编写api:再强调一遍,url用的反单引号(编写方法:因为删除用不到子组件了,所以删除都在index.vue中进行的这里用到了elementUI中的$confirm方法,去文档中复制使用即可,方法的话就不再详细解释了,前面几篇文章已经解释过了。api.delete(id).then((res)=》{//TODO})最终效果:点击删除,显示提示,传递id进行删除。
⒘springmvc怎么实现restful
⒙restful是一个风格而不是一个标准,在springmvcweb开发中可以说是兴起于Rails的一种优雅的URI表述方式,是资源的状态和状态转移的描述。springmvcrest实现springmvc的resturl是通过RequestMapping及PathVariableannotation提供的,通过如RequestMapping(value=“/blog/{id}“,method=RequestMethod.DELETE)即可处理/blog/的delete请求.Java代码RequestMapping(value=“/blog/{id}“,method=RequestMethod.DELETE)publicModelAndViewdelete(PathVariableLongid,HttpServletRequestrequest,HttpServletResponseresponse){blogManager.removeById(id);returnnewModelAndView(LIST_ACTION);}RequestMappingPathVariable如果URL中带参数,则配合使用,如Java代码RequestMapping(value=“/blog/{blogId}/message/{msgId}“,method=RequestMethod.DELETE)publicModelAndViewdelete(PathVariable(“blogId“)LongblogId,PathVariable(“msgId“)LongmsgId,HttpServletRequestrequest,HttpServletResponseresponse){}springrest配置指南.springmvcweb.xml配置Xml代码《!--该servlet为tomcat,jetty等容器提供,将静态资源映射从/改为/static/目录,如原来访问《beanclass=“.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping“/》《beanclass=“.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter“/》完整配置Java代码《beansdefault-autowire=“byName“》《!--自动搜索Controller标注的类--》《context:ponent-scanbase-package=“.**.controller“/》《beanclass=“.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping“/》《beanclass=“.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter“/》《!--DefaultViewResolver--》《beanid=“viewResolver“class=“.springframework.web.servlet.view.InternalResourceViewResolver“》《propertyname=“viewClass“value=“.springframework.web.servlet.view.JstlView“/》《propertyname=“prefix“value=“/pages“/》《propertyname=“suffix“value=“.jsp“》《/property》《/bean》《beanid=“messageSource“class=“.springframework.context.support.ResourceBundleMessageSource“p:basename=“in/messages“/》《!--Mappingexceptiontothehandlerview--》《beanid=“exceptionResolver“class=“.springframework.web.servlet.handler.SimpleMappingExceptionResolver“》《!--to/mons/error.jsp--》《propertyname=“defaultErrorView“value=“/mons/error“/》《propertyname=“exceptionMappings“》《props》《/props》《/property》《/bean》《/beans》.Controller编写Java代码/***RequestMapping(“/userinfo“)具有层次关系,方法级的将在类一级RequestMapping之一,*如下面示例,访问方法级别的RequestMapping(“/new“),则URL为/userinfo/new*/ControllerRequestMapping(“/userinfo“)publilassUserInfoControllerextendsBaseSpringController{//默认多列排序,example:usernamedesc,createTimeascprotectedstaticfinalStringDEFAULT_SORT_COLUMNS=null;privateUserInfoManageruserInfoManager;privatefinalStringLIST_ACTION=“redirect:/userinfo“;/***通过spring自动注入**/publicvoidsetUserInfoManager(UserInfoManagermanager){this.userInfoManager=manager;}/**列表*/RequestMappingpublicModelAndViewindex(HttpServletRequestrequest,HttpServletResponseresponse,UserInfouserInfo){PageRequest《Map》pageRequest=newPageRequest(request,DEFAULT_SORT_COLUMNS);//pageRequest.getFilters();//addcustomfiltersPagepage=this.userInfoManager.findByPageRequest(pageRequest);savePage(page,pageRequest,request);returnnewModelAndView(“/userinfo/list“,“userInfo“,userInfo);}/**进入新增*/RequestMapping(value=“/new“)publicModelAndView_new(HttpServletRequestrequest,HttpServletResponseresponse,UserInfouserInfo)throwsException{returnnewModelAndView(“/userinfo/new“,“userInfo“,userInfo);}/**显示*/RequestMapping(value=“/{id}“)publicModelAndViewshow(PathVariableLongid,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{UserInfouserInfo=(UserInfo)userInfoManager.getById(id);returnnewModelAndView(“/userinfo/show“,“userInfo“,userInfo);}/***/RequestMapping(value=“/{id}/edit“)publicModelAndViewedit(PathVariableLongid,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{UserInfouserInfo=(UserInfo)userInfoManager.getById(id);returnnewModelAndView(“/userinfo/edit“,“userInfo“,userInfo);}/**保存新增*/RequestMapping(method=RequestMethod.POST)publicModelAndViewcreate(HttpServletRequestrequest,HttpServletResponseresponse,UserInfouserInfo)throwsException{userInfoManager.save(userInfo);returnnewModelAndView(LIST_ACTION);}/**保存更新*/RequestMapping(value=“/{id}“,method=RequestMethod.PUT)publicModelAndViewupdate(PathVariableLongid,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{UserInfouserInfo=(UserInfo)userInfoManager.getById(id);bind(request,userInfo);userInfoManager.update(userInfo);returnnewModelAndView(LIST_ACTION);}/**删除*/RequestMapping(value=“/{id}“,method=RequestMethod.DELETE)publicModelAndViewdelete(PathVariableLongid,HttpServletRequestrequest,HttpServletResponseresponse){userInfoManager.removeById(id);returnnewModelAndView(LIST_ACTION);}/**批量删除*/RequestMapping(method=RequestMethod.DELETE)publicModelAndViewbatchDelete(RequestParam(“items“)Longitems,HttpServletRequestrequest,HttpServletResponseresponse){for(inti=;i《items.length;i++){userInfoManager.removeById(items);}returnnewModelAndView(LIST_ACTION);}}上面是rapid-framework新版本生成器生成的代码,以后也将应用此规则,resturl中增删改查等基本方法与Controller的方法映射规则Java代码/userinfo=》index()/userinfo/new=》_new()/userinfo/{id}=》show()/userinfo/{id}/edit=》edit()/userinfoPOST=》create()/userinfo/{id}PUT=》update()/userinfo/{id}DELETE=》delete()/userinfoDELETE=》batchDelete()注(不使用/userinfo/add=》add()方法是由于add这个方法会被maxthon浏览器当做广告链接过滤掉,因为包含ad字符).jsp编写Html代码《form:formaction=“${ctx}/userinfo/${userInfo.userId}“method=“put“》《/form:form》生成的html内容如下,生成一个hidden的_method=put,并于web.xml中的HiddenHttpMethodFilter配合使用,在服务端将post请求改为put请求Java代码《formid=“userInfo“action=“/springmvc_rest_demo/userinfo/“method=“post“》《inputtype=“hidden“name=“_method“value=“put“/》《/form》另外一种方法是你可以使用ajax发送put,delete请求..静态资源的URL重写如上我们描述,现因为将defaultservlet映射至/static/的子目录,现我们访问静态资源将会带一个/static/前缀.如/foo.gif,现在访问该文件将是/static/foo.gif.那如何避免这个前缀呢,那就是应用URLrewrite,现我们使用《conditionoperator=“notequal“next=“and“type=“request-uri“》.*.jsp《/condition》《conditionoperator=“notequal“next=“and“type=“request-uri“》.*.jspx《/condition》《from》^(/.*..*)$《/from》《to》/static$《/to》《/rule》《/urlrewrite》另笔者专门写了一个RestUrlRewriteFilter来做同样的事件,以后会随着rapid-framework一起发布.比这个更加轻量级.并且该代码已经贡献给spring,不知会不会在下一版本发布在线DEMO地址:
⒚RESTfulAPI设计中常见的问题和解决方案
⒛在开发HTTPAPI的时候,我们一般会按照REST风格来设计,符合REST风格的API也称为RESTfulAPI。RESTfulAPI的主要规则包括以下几点:标准的RESTfulAPI示例如下:由于英语语法的特点和HTTP请求的方法数量的有限,可能存在一些无法覆盖到的部分,如下:下面来谈谈上述未覆盖部分及其解决方案。常规动作有GET,POST,PUT,PATCH和DELETE,也就是所谓的增删改查,但是现实中还有很多非前面提到的动作,如取消操作。针对非常规动作,解决的方案有两种:下面我们以取消订单为例,来看看针对该问题不同方案的实现。该方案是GitHub在使用中的方案,在开放的API的可以看到。针对实例的实现如下:这个GoogleCould中CouldAPI设计规范中定义的方案,语法为:针对实例的实现如下:该情况可按照英语语法使用对应的名词即可,如下:使用可数名词来代替,如news可以用news-items来代替。这种情况可以采用资源对应的名词的单数形式来表示获取一条数据,该方案也适用于多对一的情况。例如:用户的购物车数据,每个用户有一个购物车,可以表示如下: