电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

金蝶云苍穹-自定义API2.0开发案例(最终版).pdf

金蝶云苍穹-自定义API2.0开发案例(最终版).pdf_第1页
1/14
金蝶云苍穹-自定义API2.0开发案例(最终版).pdf_第2页
2/14
金蝶云苍穹-自定义API2.0开发案例(最终版).pdf_第3页
3/14
新增注解说明kd.bos.openapi.common.custom.annotation.ApiHeaders请求头注解kd.bos.openapi.common.custom.annotation.ApiHeader请求头注解kd.bos.openapi.common.custom.annotation.ApiErrorCodes错误代码注解kd.bos.openapi.common.custom.annotation.ApiErrorCode错误代码注解新增注解说明kd.bos.openapi.common.custom.annotation.ApiRequestBody请求体注解,标记的model作为api的请求体参数kd.bos.openapi.common.custom.annotation.ApiResponseBody响应体注解自定义API2.0开发案例新特性BOS_V5.0.009标记在类上的请求头和错误代码为类中方法共有,标记方法上的为该方法独有BOS_V5.0.008@ApiController(value="open",desc="用户example")@ApiMapping("/example")@ApiHeaders({@ApiHeader(name="a",desc="aa",example="aaa"),@ApiHeader(name="b",desc="bb",example="bbb")})@ApiErrorCodes({@ApiErrorCode(code="001",desc="0001"),@ApiErrorCode(code="002",desc="0002")})publicclassExampleControllerimplementsSerializable{@ApiHeaders({@ApiHeader(name="e",desc="ee",example="eee"),@ApiHeader(name="f",desc="ff",example="fff"),})@ApiErrorCodes({@ApiErrorCode(code="005",desc="0005"),@ApiErrorCode(code="006",desc="0006")})@Validated@ApiPostMapping("/bodyExample")Jar说明bos-open-api-*.jar定义注解类jakarta.validation-api-.jar,hibernate-validator-.jar注解校验类依赖依赖jar包注解类定义类需要设置@ApiController注解示例1(推荐)publicCustomApiResult<@ApiResponseBody("响应")Xxx>bodyExample(@Valid@NotNull@ApiRequestBody(value="用户信息")XxxModelexampleModel){returnCustomApiResult.success(exampleModel1);}}kd.bos.openapi.common.custom.annotation.ApiControllerkd.bos.openapi.common.custom.annotation.ApiGetMappingkd.bos.openapi.common.custom.annotation.ApiPostMappingkd.bos.openapi.common.custom.annotation.ApiMappingkd.bos.openapi.common.custom.annotation.ApiModelkd.bos.openapi.common.custom.annotation.ApiParamkd.bos.openapi.common.custom.annotation.ApiRequestBodykd.bos.openapi.common.custom.annotation.ApiResponseBodykd.bos.openapi.common.custom.annotation.ApiHeaderskd.bos.openapi.common.custom.annotation.ApiHeaderkd.bos.openapi.common.custom.annotation.ApiErrorCodeskd.bos.openapi.common.custom.annotation.ApiErrorCode@ApiController(value="bos",desc="demo样例")@ApiMapping(value="demo")publicclassCustomDemoControllerimplementsSerializable{}示例2方法定义方法需设置@ApiGetMapping或@ApiPostMapping注解方法参数需设置@ApiParam注解,model参数类需要设置@ApiModel注解或继承CustomApiBaseModel,model只解析设置@ApiParam注解的属性方法返回值必须是CustomApiResult且要指定泛型Get请求方法需设置@ApiGetMapping注解,方法参数只能是基本类型示例1(推荐)示例2不对参数进行校验Post请求(推荐)方法需设置@ApiPostMapping注解,方法参数支持任何复杂类型示例1(推荐)model类需要设置@ApiModel注解,model只解析设置@ApiParam注解的属性,model需要实现Serializable序列化。@ApiController("bos")publicclassCustomDemoControllerimplementsSerializable{}@ApiGetMapping(value="demo1")publicCustomApiResult<@ApiResponseBody(value="返回参数",example="1")Integer>demo1(@Min(10)@ApiParam(value="序号")Integeri,@Length(min=9)@NotBlank@ApiParam(value="字符串")Strings){//todo-处理逻辑}@ApiGetMapping(value="demo1/test")publicCustomApiResult<@ApiResponseBody(value="返回参数",example="a")String>demo1(@ApiParam(value="序号")Integeri,@ApiParam(value="序号")Strings){//todo-处理逻辑}@ApiPostMapping(value="/demo3",desc="测试demo3")publicCustomApiResult<@ApiResponseBody("返回参数")CustomSuperDemoModel>demo3(@NotNull@Valid@ApiParam(value="demo模型")CustomDemoModelmodel){//todo-处理逻辑}@ApiPostMapping(value="/demo3",desc="测试demo3")publicCustomApiResult<@ApiResponseBody("返回参数")CustomSuperDemoModel>demo3(@NotNull@Valid@ApiRequestBody(value="demo模型")CustomDemoModelmodel){//todo-处理逻辑}//----------------------------下面为CustomDemoModel定义---------------------------------@ApiModelpublicclassCustomDemoModelimplementsSerializable{privatestaticfinallongserialVersionUID=-2287273230483521474L;@ApiParam("ID")privateLongid;@Length(min=5)@NotBlank@ApiParam(value="编码",required=true)privateStringnumber;@ApiParam(value="名称",required=true)privateStringname;@ApiParam("日期")privateDatedate;@ApiParam("Byte")privateBytebyte1;@ApiParam("Character")privateCharactercharacter;@ApiParam("Short")privateShortaShort;@ApiParam("Double")privateDoubleaDouble;@ApiParam("float")privatefloataFloat;@ApiParam("日期时间")privateDatedateTime;@ApiParam("年龄")privateintage;@ApiParam("是否")privatebooleanisMale;@ApiParam("小数")privateBigDecimaldecimal;@ApiParam(value="int数组",position=7)privateint[]ints;@ApiParam(value="int[][]",position=7)privateint[][]ints3;@ApiParam(value="int数组",position=7)privateSet[]ints2;@ApiParam(value="long集合",position=6,example="[111a,222]")privateListlongList;@ApiParam(value="List",position=6)privateListlongList2;@ApiParam(value="String集合",position=5,example="[\"aaa\",\"bbb\"]")privateSetstringSet;@ApiParam(value="CustomChildDemoModel",position=6,required=true)privateCustomChildDemoModelchildDemoModel;@Size(min=3,max=6)@ApiParam(value="分录",position=8,required=true)privateListchildList;@ApiParam(value="数组",position=8)privateCustomChildDemoModel[]models;@ApiParam(value="Map",position=8)privateMap>>map;@ApiParam(value="Class",position=9)privateClasscls;//省略getset}@ApiModelpublicclassCustomSuperDemoModelimplementsSerializable{@ApiParam(value="one",position=4)privateStringone;privateStringtwo;//省略getset}注解说明必须属性说明@ApiController自定义API类标识是value:应用编码,eg:bosdesc:描述@ApiMapping请求路径否value:请求路径,eg:/user示例2请求地址变量说明描述{ISV}开发商标识开发商标识为kingdee时不显示{appId}应用Id{api_number}api编码编码是(类的@ApiMapping注解值)+(方法的@ApiPostMapping或@ApiGetMapping的注解值)1.自定义API请求地址/v2/{ISV}/{appId}/{api_number}总结自定义API开发总结类需要实现java.io.Serializable序列化方法@ApiPostMapping和@ApiGetMapping只能有一个最终生成的请求路径是类上的@ApiMapping+方法上的@ApiPostMapping/@ApiGetMapping@ApiPostMapping(value="demo2")publicCustomApiResult<@ApiResponseBody("返回参数")Map>demo2(@ApiParam(value="入参map")Mapmap){//todo-处理逻辑}注解说明必须属性说明@ApiPostMapping请求方式,POST请求是value:请求路径,eg:/adddesc:描述@ApiGetMapping请求方式,GET请求是value:请求路径,eg:/query/alldesc:描述注解说明必须属性说明@ApiParam参数是value:描述required:是否必填example:参数示例@ApiRequestBody请求体:适用于POST请求,且方法只有一个Model参数是value:描述required:是否必填方法入参一个方法的参数中@ApiParam和@ApiRequestBody只能有一个@ApiParam@ApiRequestBody@ApiPostMapping("/bodyExample")publicCustomApiResult<@ApiResponseBody("Body")XxxModel1>bodyExample(@ApiParam(value="用户信息")XxxModel2model2){//TODOreturnCustomApiResult.success(XxxModel1);}//@ApiParam解析{"model2":{"userId":"1661764483634","userName":"RlbT5","account":"k7X0b","password":"HUogf"}}@ApiPostMapping("/bodyExample")publicCustomApiResult<@ApiResponseBody("Body")XxxModel1>bodyExample(@ApiRequestBody(value="用户信息")XxxModel2model2){//TODOreturnCustomApiResult.success(XxxModel1);}注解说明必须属性说明@ApiResponseBody响应体:只能标记CustomApiResult的泛型,例:CustomApiResult<@ApiResponseBody("Body")XxxModel1>否value:描述example:参数示例注解说明必须属性说明@ApiModelmodel类注解是无@ApiParammodel属性注解是value:描述required:是否必填example:参数示例方法出参方法返回结果必须是CustomApiResultModel模型定义需要实现java.io.Serializable序列化参数校验方便对参数进行校验,自定义API集成了JavaAPI规范(JSR303)定义的Bean校验标准validation-api。可以像使用SpringValidation,HibernateValidation一样对参数进行注解校验配置。在Model字段上声明约束注解//@ApiRequestBody解析{"userId":"1661764483634","userName":"RlbT5","account":"k7X0b","password":"HUogf"}@ApiModelpublicclassUserModelimplementsSerializable{@ApiParam("用户ID")privateLonguserId;@ApiParam("用户名")@NotNull@Length(min=2,max=10)privateStringuserName;在方法参数上声明校验注解分组校验约束注解上声明适用的分组信息groups@ApiParam("账号")@NotNull@Length(min=6,max=20)privateStringaccount;@ApiParam("密码")@NotNull@Length(min=6,max=20)privateStringpassword;//省略get/set}@ApiPostMapping("/save")publicCustomApiResult<@ApiResponseBody("返回参数")xxx>saveUser(@ApiParam("用户信息")@ValidUserModeluserModel){//校验通过,才会执行业务逻辑处理//TODOreturnCustomApiResult.success(xxx);}@ApiModelpublicclassUserModelimplementsSerializable{@ApiParam("用户ID")@Min(value=10000000000000000L,groups=Update.class)privateLonguserId;@ApiParam("用户名")@NotNull(groups={Save.class,Update.class})@Length(min=2,max=10,groups={Save.class,Update.class})privateStringuserName;@ApiParam("账号")@NotNull(groups={Save.class,Update.class})@Length(min=6,max=20,groups={Save.class,Update.class})privateStringaccount;@ApiParam("密码")@NotNull(groups={Save.class,Update.class})@Length(min=6,max=20,groups={Save.class,Update.class})privateStringpassword;/***保存的时候校验分组*/publicinterfaceSave{}@Validated注解上指定校验分组嵌套校验前面的示例中,Model类里面的字段都是基本数据类型和String类型。但是实际场景中,有可能某个字段也是一个对象,这种情况先,可以使用嵌套校验。比如,上面保存User信息的时候同时还带有Job信息。需要注意的是,此时Model类的对应字段必须标记@Valid注解。/***更新的时候校验分组*/publicinterfaceUpdate{}}@ApiPostMapping("/save")@Validated(UserModel.Save.class)//指定校验分组publicCustomApiResult<@ApiResponseBody("返回参数")xxx>saveUser(@Valid@ApiParam("用户信息")UserModeluserModel){//@Valid指定校验属性//校验通过,才会执行业务逻辑处理//TODOreturnCustomApiResult.success(xxx);}@ApiPostMapping("/update")@Validated(UserModel.Update.class)//指定校验分组publicCustomApiResult<@ApiResponseBody("返回参数")xxx>updateUser(@ApiParam("用户信息")@ValidUserModeluserModel){//@Valid指定校验属性//校验通过,才会执行业务逻辑处理//TODOreturnCustomApiResult.success(xxx);}@ApiModelpublicclassUserModelimplementsSerializable{@ApiParam("用户ID")@Min(value=10000000000000000L,groups=Update.class)privateLonguserId;@ApiParam("用户名")@NotNull(groups={Save.class,Update.class})@Length(min=2,max=10,groups={Save.class,Update.class})privateStringuserName;@ApiParam("账号")@NotNull(groups={Save.class,Update.class})@Length(min=6,max=20,groups={Save.class,Update.class})privateStringaccount;@ApiParam("密码")@NotNull(groups={Save.class,Update.class})@Length(min=6,max=20,groups={Save.class,Update.class})privateStringpassword;嵌套校验可以结合分组校验一起使用。还有就是嵌套集合校验会对集合里面的每一项都进行校验,例如List字段会对这个list里面的每一个Job对象都进行校验。自定义校验业务需求总是比框架提供的这些简单校验要复杂的多,我们可以自定义校验来满足我们的需求。自定义springvalidation非常简单,假设我们自定义加密id(由数字或者a-f的字母组成,32-256长度)校验,主要分为两步:自定义约束注解@ApiParam("职位")@NotNull(groups={Save.class,Update.class})@Valid//注意一定要标记此注解privateJobjob;@ApiParam("职位")@NotNull(groups={Save.class,Update.class})@Valid//注意一定要标记此注解publicListlist;@ApiModelpublicstaticclassJobimplementsSerializable{@ApiParam("职位id")@Min(value=1,groups=Update.class)privateLongjobId;@ApiParam("职位名称")@NotNull(groups={Save.class,Update.class})@Length(min=2,max=10,groups={Save.class,Update.class})privateStringjobName;@ApiParam("职位")@NotNull(groups={Save.class,Update.class})@Length(min=2,max=10,groups={Save.class,Update.class})privateStringposition;}/***保存的时候校验分组*/publicinterfaceSave{}/***更新的时候校验分组*/publicinterfaceUpdate{}}@Target({METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER})@Retention(RUNTIME)@Documented@Constraint(validatedBy={EncryptIdValidator.class})public@interfaceEncryptId{实现ConstraintValidator接口编写约束校验器这样我们就可以使用@EncryptId进行参数校验了!编程式校验上面的示例都是基于注解来实现自动校验的,在某些情况下,我们可能希望以编程方式调用验证。这个时候可以通过kd.bos.openapi.service.custom.validation.ValidatorUtil工具类进行验证。//默认错误消息Stringmessage()default"加密id格式错误";//分组Class[]groups()default{};//负载Class[]payload()default{};}publicclassEncryptIdValidatorimplementsConstraintValidator{privatestaticfinalPatternPATTERN=Pattern.compile("^[a-f\\d]{32,256}$");@OverridepublicbooleanisValid(Stringvalue,ConstraintValidatorContextcontext){//不为null才进行校验if(value!=null){Matchermatcher=PATTERN.matcher(value);returnmatcher.find();}returntrue;}}//编程式校验@ApiPostMapping("/saveWithCodingValidate")publicCustomApiResult<@ApiResponseBody("返回参数")xxx>saveWithCodingValidate(@ApiParam("用户信息")UserModeluserModel){Set>validate=ValidatorUtil.validate(userModel,UserModel.Save.class);//如果校验通过,validate为空;否则,validate包含未校验通过项if(validate.isEmpty()){//校验通过,才会执行业务逻辑处理//TODOreturnCustomApiResult.success(xxx);}else{for(ConstraintViolationuserModelConstraintViolation:validate){//校验失败,做其它逻辑}returnCustomApiResult.fail("xxxx","xxx");更多校验请参考SpringValidation,HibernateValidation扩展能力1.自定义API请求参数和响应结果是通过FastJson序列化和反序列化,因此可以使用FastJson序列化和反序列化的一些特性BestPracticeforJSONFastjson(JSONFastjson最佳实践)·alibaba/fastjsonWiki(github.com)}}packagecom.alibaba.fastjson.annotation;public@interfaceJSONField{/***配置序列化/反序列化的顺序*configencode/decodeordinal*@since1.1.42*@return*/intordinal()default0;/***日期类型进行序列化/反序列化的格式*/Stringformat()default"";/***是否序列化*/booleanserialize()defaulttrue;/***是否反序列化*/booleandeserialize()defaulttrue;/***序列化选项*/SerializerFeature[]serialzeFeatures()default{};/***反序列化选项*/Feature[]parseFeatures()default{};/***指定序列化方式:类需要实现ObjectSerializer接口*Serializerclasstouseforserializingassociatedvalue.*2.JakartaBeanValidation-JakartaBeanValidation2.03.HibernateValidator6.2.4.Final-JakartaBeanValidationReferenceImplementation:ReferenceGuide(jboss.org)*@since1.2.16*/ClassserializeUsing()defaultVoid.class;/***指定反序列化方式:类需要实现ObjectDeserializer接口*Deserializerclasstousefordeserializingassociatedvalue.**@since1.2.16*/ClassdeserializeUsing()defaultVoid.class;}//配置date序列化和反序列使用yyyyMMdd日期格式@JSONField(format="yyyyMMdd")publicDatedate1;//不序列化@JSONField(serialize=false)publicDatedate2;//不反序列化@JSONField(deserialize=false)publicDatedate3;//按ordinal排序@JSONField(ordinal=2)privateintf1;@JSONField(ordinal=1)privateintf2;

1、当您付费下载文档后,您只拥有了使用权限,并不意味着购买了版权,文档只能用于自身使用,不得用于其他商业用途(如 [转卖]进行直接盈利或[编辑后售卖]进行间接盈利)。
2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。
3、如文档内容存在违规,或者侵犯商业秘密、侵犯著作权等,请点击“违规举报”。

碎片内容

金蝶云苍穹-自定义API2.0开发案例(最终版).pdf

确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信