springmvc接口支持form入参 springmvc调用接口

admin2024-06-06  15

一、关于SpringMVC接口定义要注意以下常见的几种问题
1. 返回格式不统一
同一个接口,有时候返回数组,有时候返回单个;成功的时候返回对象,失败的时候返回错误信息字符串。工作中有个系统集成就是这样定义的接口,真是辣眼睛。这个对应代码上,返回的类型是map,json,object,都是不应该的。实际工作中,我们会定义一个统一的格式,就是ResultBean,分页的有另外一个PageResultBean
错误范例:

//返回map可读性不好,尽量不要 
 @PostMapping("/delete") 
 public Map<String, Object> delete(long id, String lang) { } 
 // 成功返回boolean,失败返回string,大忌 
 @PostMapping("/delete") 
 public Objectdelete(long id, String lang) { 
 try { 
 boolean result = configService.delete(id, local); return result; 
 } catch (Exception e) {
  log.error(e); return e.toString(); 
 } 
 }

2. 没有考虑失败情况
一开始只考虑成功场景,等后面测试发现有错误情况,怎么办,改接口呗,前后台都改,劳民伤财无用功。
错误范例:

//不返回任何数据,没有考虑失败场景,容易返工 
 @PostMapping("/update") public void update(long id, xxx) { }

3. 出现和业务无关的输入参数
如lang语言,当前用户信息 都不应该出现参数里面,应该从当前会话里面获取。后面讲ThreadLocal会说到怎么样去掉。除了代码可读性不好问题外,尤其是参数出现当前用户信息的,这是个严重问题。
错误范例:

// (当前用户删除数据)参数出现lang和userid,尤其是userid,大忌 
 @PostMapping("/delete") 
 public Map<String, Object> delete(long id,String lang, String userId) { }

4. 出现复杂的输入参数
一般情况下,不允许出现例如json字符串这样的参数,这种参数可读性极差。应该定义对应的bean。
错误范例:

// 参数出现json格式,可读性不好,代码也难看 
 @PostMapping("/update") public Map<String, Object> update(long id, String jsonStr) { }

5. 没有返回应该返回的数据
例如,新增接口一般情况下应该返回新对象的id标识,这需要编程经验。新手定义的时候因为前台没有用就不返回数据或者只返回true,这都是不恰当的。别人要不要是别人的事情,你该返回的还是应该返回。
错误范例:

// 约定俗成,新建应该返回新对象的信息,只返回boolean容易导致返工 
 @PostMapping("/add") 
 public boolean add(xxx) { //xxx return configService.add(); }

很多人看了我的这篇文章程序员你为什么这么累?,都觉得里面的技术也很简单,没有什么特别的地方,但是,实现这个代码框架之前,就是要你的接口的统一的格式ResultBean,aop才好做。有些人误解了,我那篇文章说的都不是技术,重点说的是编码习惯工作方式,如果你重点还是放在什么技术上,那我也帮不了你了。同样,如果我后面的关于习惯和规范的帖子,你重点还是放在技术上的话,那是丢了西瓜捡芝麻,有很多贴还是没有任何技术点呢。
附上ResultBean,没有任何技术含量:

@Data
 public class ResultBean<T> implements Serializable {
  privatestatic final long serialVersionUID = 1L; 
 public static final intSUCCESS = 0; 
 public static final int FAIL = 1; 
 public static final intNO_PERMISSION = 2; 
 private String msg = "success"; 
 private int code = SUCCESS; private T data; 
 public ResultBean() { 
 super();
 } 
 public ResultBean(T data) {
 super(); this.data = data; 
 } 
 public ResultBean(Throwable e) {
 super(); this.msg = e.toString(); this.code = FAIL ; 
 }
 }


统一的接口规范,能帮忙规避很多无用的返工修改和可能出现的问题。能使代码可读性更加好,利于进行aop和自动化测试这些额外工作。

二、关于Controller规范

主要的内容是就是接口定义里面的内容,你只要遵循里面的规范,controller就问题不大,除了这些,还有另外的几点:(1)所有函数返回统一的ResultBean/PageResultBean格式;(2)没有统一格式,AOP无法玩.(3)ResultBean/PageResultBean是controller专用的,不允许往后传!(4)Controller做参数格式的转换,不允许把json,map这类对象传到services去,也不允许services返回json、map。

一般情况下!写过代码都知道,map,json这种格式灵活,但是可读性差,如果放业务数据,每次阅读起来都比较困难。定义一个bean看着工作量多了,但代码清晰多了。
参数中一般情况不允许出现Request,Response这些对象
主要是可读性问题。一般情况下。
不需要打印日志
日志在AOP里面会打印,而且我的建议是大部分日志在Services这层打印。
规范里面大部分是 不要做的项多,要做的比较少,落地比较容易。
ResultBean定义带泛型,使用了lombok。
为什么总说程序员累成狗续:编码习惯之Controller规范
AOP代码,主要就是打印日志和捕获异常,异常要区分已知异常和未知异常,其中未知的异常是我们重点关注的,可以做一些邮件通知啥的,已知异常可以再细分一下,可以不同的异常返回不同的返回码:

public class ControllerAOP {
 private static final Logger logger=LoggerFactory.getLogger(ControllerAOP.class);
 public ObjecthandlerControllerMethod(ProceedingJoinPoint pjp) {
 long startTime =System.currentTimeMillis();
 ResultBean<?> result;
 try {
 result = (ResultBean<?>) pjp.proceed();
 logger.info(pjp.getSignature() + "use time:" + (System.currentTimeMillis() - startTime));
 } catch (Throwable e) {
 result = handlerException(pjp, e);
 }return result;
 }
 private ResultBean<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
 ResultBean<?>result = new ResultBean();
 // 已知异常
 if (e instanceof CheckException){
 result.setMsg(e.getLocalizedMessage());
 result.setCode(ResultBean.FAIL);
 }else {
 logger.error(pjp.getSignature() + " error ", e);
 result.setMsg(e.toString());
 result.setCode(ResultBean.FAIL);
 // 未知异常是应该重点关注的,这里可以做其他操作,如通知邮件,单独写到某个文件等等。
 }
 return result;
 }
 }


AOP配置:(关于用java代码还是xml配置,这里我倾向于xml配置,因为这个会不定期改动)

<!-- aop -->
 <aop:aspectj-autoproxy />
 <beans:beanid="controllerAop"class="xxx.common.aop.ControllerAOP" />
 <aop:config>
 <aop:aspect id="myAop"ref="controllerAop">
 <aop:pointcutid="target"expression="execution(public xxx.common.beans.ResultBean *(..))" /><aop:aroundmethod="handlerControllerMethod" pointcut-ref="target" />
 </aop:aspect>
 </aop:config>

现在知道为什么要返回统一的一个ResultBean了:
为了统一格式
为了应用AOP
为了包装异常信息
分页的PageResultBean大同小异。

 End...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!