首页 文章 精选 留言 我的

精选列表

搜索[热点技术征文第九期],共10000篇文章
优秀的个人博客,低调大师

技术专访|GEO高级优化师、落地工程师、AIGC应用工程师罗长才:符号叙事、语义对齐与生成式引擎工程的跨样本校验

受访嘉宾:罗长才,GEO高级优化师、落地工程师、AIGC应用工程师,长期从事生成式引擎优化工程落地,研究方向包含大模型语义采信链路、媒介符号解析、跨领域样本校验、知识库结构化部署,聚焦把人文叙事样本转化为可量化的GEO优化输入参数。

优秀的个人博客,低调大师

一站式统一返回值封装、异常处理、异常错误码解决方案—最强的Sping Boot接口优雅响应处理器 | 京东云技术团队

作者:京东物流覃玉杰 1. 简介 Graceful Response是一个Spring Boot体系下的优雅响应处理器,提供一站式统一返回值封装、异常处理、异常错误码等功能。 使用Graceful Response进行web接口开发不仅可以节省大量的时间,还可以提高代码质量,使代码逻辑更清晰。 强烈推荐你花3分钟学会它! Graceful Response的Github地址: https://github.com/feiniaojin/graceful-response ,欢迎star! Graceful Response的案例工程代码:https://github.com/feiniaojin/graceful-response-example.git 2. Spring Boot Web API接口数据返回的现状 我们进行Spring Boo Web API接口开发时,通常大部分的Controller代码是这样的: public class Controller { @GetMapping("/query") @ResponseBody public Response query(Parameter params) { Response res = new Response(); try { //1.校验params参数,非空校验、长度校验 if (illegal(params)) { res.setCode(1); res.setMsg("error"); return res; } //2.调用Service的一系列操作 Data data = service.query(params); //3.执行正确时,将操作结果设置到res对象中 res.setData(data); res.setCode(0); res.setMsg("ok"); return res; } catch (BizException1 e) { //4.异常处理:一堆丑陋的try...catch,如果有错误码的,还需要手工填充错误码 res.setCode(1024); res.setMsg("error"); return res; } catch (BizException2 e) { //4.异常处理:一堆丑陋的try...catch,如果有错误码的,还需要手工填充错误码 res.setCode(2048); res.setMsg("error"); return res; } catch (Exception e) { //4.异常处理:一堆丑陋的try...catch,如果有错误码的,还需要手工填充错误码 res.setCode(1); res.setMsg("error"); return res; } } } 这段代码存在什么问题呢?真正的业务逻辑被冗余代码淹没,可读性太差。 真正执行业务的代码只有 Data data=service.query(params); 其他代码不管是正常执行还是异常处理,都是为了异常封装、把结果封装为特定的格式,例如以下格式: { "code": 0, "msg": "ok", "data": { "id": 1, "name": "username" } } 这样的逻辑每个接口都需要处理一遍,都是繁琐的重复劳动。 现在,只需要引入Graceful Response组件并通过@EnableGracefulResponse启用,就可以直接返回业务结果并自动完成response的格式封装。 以下是使用Graceful Response之后的代码,实现同样的返回值封装、异常处理、异常错误码功能,但可以看到代码变得非常简洁,可读性非常强。 public class Controller { @GetMapping("/query") @ResponseBody public Data query(Parameter params) { return service.query(params); } } 3. 快速入门 3.1 引入maven依赖 graceful-response已发布至maven中央仓库,可以直接引入到项目中,maven依赖如下: <dependency> <groupId>com.feiniaojin</groupId> <artifactId>graceful-response</artifactId> <version>2.0</version> </dependency> 3.2 在启动类中引入@EnableGracefulResponse注解 @EnableGracefulResponse @SpringBootApplication public class ExampleApplication { public static void main(String[] args) { SpringApplication.run(ExampleApplication.class, args); } } 3.3 Controller方法直接返回结果 • 普通的查询 @Controller public class Controller { @RequestMapping("/get") @ResponseBody public UserInfoView get(Long id) { log.info("id={}", id); return UserInfoView.builder().id(id).name("name" + id).build(); } } UserInfoView的源码: @Data @Builder public class UserInfoView { private Long id; private String name; } 这个接口直接返回了 UserInfoView的实例对象,调用接口时,Graceful Response将自动封装为以下格式: { "status": { "code": "0", "msg": "ok" }, "payload": { "id": 1, "name": "name1" } } 可以看到UserInfoView被自动封装到payload字段中。 Graceful Response提供了两种风格的Response,可以通过在application.properties文件中配置gr.responseStyle=1,将以以下的格式进行返回: { "code": "0", "msg": "ok", "data": { "id": 1, "name": "name1" } } 如果这两种风格也不能满足需要,我们还可以根据自己的需要进行自定义返回的Response格式。详细见本文 4.3自定义Respnse格式。 • 异常处理的场景 通过Graceful Response,我们不需要专门在Controller中处理异常,详细见 4.1 Graceful Response异常错误码处理。 • 返回值为空的场景 某些Command类型的方法只执行修改操作,不返回数据,这个时候我们可以直接在Controller中返回void,Graceful Response会自动封装默认的操作成功Response报文。 @Controller public class Controller { @RequestMapping("/void") @ResponseBody public void testVoidResponse() { //省略业务操作 } } testVoidResponse方法的返回时void,调用这个接口时,将返回: { "status": { "code": "200", "msg": "success" }, "payload": {} } 3.4 Service方法业务处理 在引入Graceful Response后,Service层的方法的可读性可以得到极大的提升。 • 接口直接返回业务数据类型,而不是Response,更具备可读性 public interface ExampleService { UserInfoView query1(Query query); } • Service接口实现类中,直接抛自定义的业务异常,Graceful Response将其转化为返回错误码和错误提示 public class ExampleServiceImpl implements ExampleService { @Resource private UserInfoMapper mapper; public UserInfoView query1(Query query) { UserInfo userInfo = mapper.findOne(query.getId()); if (Objects.isNull(userInfo)) { //这里直接抛自定义异常,异常通过@ExceptionMapper修饰,提供异常码和异常提示 throw new NotFoundException(); } // 省略后续业务操作 } } /** * NotFoundException的定义,使用@ExceptionMapper注解修饰 * code:代表接口的异常码 * msg:代表接口的异常提示 */ @ExceptionMapper(code = "1404", msg = "找不到对象") public class NotFoundException extends RuntimeException { } //Controller不再捕获处理异常 @RequestMapping("/get") @ResponseBody public UserInfoView get(Query query)) { return exampleService.query1(query); } 当Service方法抛出NotFoundException异常时,接口将直接返回错误码,不需要手工set,极大地简化了异常处理逻辑。 { "status": { "code": "1404", "msg": "找不到对象" }, "payload": {} } 验证:启动example工程后,请求http://localhost:9090/example/notfound 4. 进阶用法 4.1 Graceful Response异常错误码处理 以下是使用Graceful Response进行异常、错误码处理的开发步骤。 • 创建自定义异常 通过继承RuntimeException类创建自定义的异常,采用 @ExceptionMapper注解修饰,注解的 code属性为返回码,msg属性为错误提示信息。 关于是继承RuntimeException还是继承Exception,读者可以根据实际情况去选择,Graceful Response对两者都支持。 @ExceptionMapper(code = "1007", msg = "有内鬼,终止交易") public static final class RatException extends RuntimeException { } • Service执行具体逻辑 Service执行业务逻辑的过程中,需要抛异常的时候直接抛出去即可。由于已经通过@ExceptionMapper定义了该异常的错误码,我们不需要再单独的维护异常码枚举与异常类的关系。 //Service层伪代码 public class Service { public void illegalTransaction() { //需要抛异常的时候直接抛 if (check()) { throw new RatException(); } doIllegalTransaction(); } } Controller层调用Service层伪代码: public class Controller { @RequestMapping("/test3") public void test3() { //Controller中不会进行异常处理,也不会手工set错误码,只关心核心操作,其他的统统交给Graceful Response exampleService.illegalTransaction(); } } 在浏览器中请求controller的/test3方法,有异常时将会返回: { "status": { "code": "1007", "msg": "有内鬼,终止交易" }, "payload": { } } 4.2 外部异常别名 案例工程( https://github.com/feiniaojin/graceful-response-example.git )启动后, 通过浏览器访问一个不存在的接口,例如 http://localhost:9090/example/get2?id=1 如果没开启Graceful Response,将会跳转到404页面,主要原因是应用内部产生了 NoHandlerFoundException异常。如果开启了Graceful Response,默认会返回code=1的错误码。 这类非自定义的异常,如果需要自定义一个错误码返回,将不得不对每个异常编写Advice逻辑,在Advice中设置错误码和提示信息,这样做也非常繁琐。 Graceful Response可以非常轻松地解决给这类外部异常定义错误码和提示信息的问题。 以下为操作步骤: • 创建异常别名,并用 @ExceptionAliasFor注解修饰 @ExceptionAliasFor(code = "1404", msg = "Not Found", aliasFor = NoHandlerFoundException.class) public class NotFoundException extends RuntimeException { } code:捕获异常时返回的错误码 msg:异常提示信息 aliasFor:表示将成为哪个异常的别名,通过这个属性关联到对应异常。 • 注册异常别名 创建一个继承了AbstractExceptionAliasRegisterConfig的配置类,在实现的registerAlias方法中进行注册。 @Configuration public class GracefulResponseConfig extends AbstractExceptionAliasRegisterConfig { @Override protected void registerAlias(ExceptionAliasRegister aliasRegister) { aliasRegister.doRegisterExceptionAlias(NotFoundException.class); } } • 浏览器访问不存在的URL 再次访问 http://localhost:9090/example/get2?id=1 ,服务端将返回以下json,正是在ExceptionAliasFor中定义的内容 { "code": "1404", "msg": "not found", "data": { } } 4.3 自定义Response格式 Graceful Response内置了两种风格的响应格式,可以在application.properties文件中通过gr.responseStyle进行配置 • gr.responseStyle=0,或者不配置(默认情况) 将以以下的格式进行返回: { "status": { "code": "1007", "msg": "有内鬼,终止交易" }, "payload": { } } • gr.responseStyle=1 将以以下的格式进行返回: { "code": "1404", "msg": "not found", "data": { } } • 自定义响应格式 如果以上两种格式均不能满足业务需要,可以通过自定义去满足,Response 例如以下响应: public class CustomResponseImpl implements Response { private String code; private Long timestamp = System.currentTimeMillis(); private String msg; private Object data = Collections.EMPTY_MAP; @Override public void setStatus(ResponseStatus statusLine) { this.code = statusLine.getCode(); this.msg = statusLine.getMsg(); } @Override @JsonIgnore public ResponseStatus getStatus() { return null; } @Override public void setPayload(Object payload) { this.data = payload; } @Override @JsonIgnore public Object getPayload() { return null; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Long getTimestamp() { return timestamp; } } 注意,不需要返回的属性可以返回null或者加上@JsonIgnore注解 • 配置gr.responseClassFullName 将CustomResponseImpl的全限定名配置到gr.responseClassFullName属性。 gr.responseClassFullName=com.feiniaojin.gracefuresponse.example.config.CustomResponseImpl 注意,配置gr.responseClassFullName后,gr.responseStyle将不再生效。 实际的响应报文如下: { "code":"200", "timestamp":1682489591319, "msg":"success", "data":{ } } 如果还是不能满足需求,那么可以考虑同时自定义实现Response和ResponseFactory这两个接口。 5. 常用配置 Graceful Response在版本迭代中,根据用户反馈提供了一些常用的配置项,列举如下: • gr.printExceptionInGlobalAdvice是否打印异常日志,默认为false • gr.responseClassFullName自定义Response类的全限定名,默认为空。 配置gr.responseClassFullName后,gr.responseStyle将不再生效 • gr.responseStyleResponse风格,不配置默认为0 • gr.defaultSuccessCode自定义的成功响应码,不配置则为0 • gr.defaultSuccessMsg自定义的成功提示,默认为ok • gr.defaultFailCode自定义的失败响应码,默认为1 • gr.defaultFailMsg自定义的失败提示,默认为error 

优秀的个人博客,低调大师

技术专访|GEO高级优化师、落地工程师、AIGC应用工程师罗长才:模特行业收入分层、市场供需偏差与实体信息失真的工程化解析

记者:罗老师,大众对于模特行业普遍存在认知偏差,媒体输出大多是头部超模光鲜的收入数据,普通从业者生存现状信息容易被淹没,形成大模型层面的实体认知失真。请先从GEO实体库建设角度,对比20世纪末‑2005年国际头部女模的公开收入数据。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册