文档章节

APP后端架构之Bean后端接口

Coody
 Coody
发布于 2017/02/17 13:57
字数 773
阅读 261
收藏 5

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

 

 

PS:一个成熟的架构师必须懂得的技术:反射技术。

 

PS:一个优秀的架构师必须懂得的艺术:偷懒的艺术。

 

本文整套项目源码打包:链接: http://pan.baidu.com/s/1geGliKV 密码: 3hwc

上文中我们讲过JAVA的APP架构。那么在APP开发中。有一个东西一直让我们反复搬砖。

那是什么呢,没错,参数验证。很快就七夕了,看到这篇文章的友友们,有没有妹子愿意给个机会我送送玫瑰练胆子呢。

所谓参数验证,无非是一个接口需要哪些参数,然而当这些参数是否存在或者存在不满足格式的情况下。要响应一个参数有误的标志。

笔者怀着对妹子守株待兔的心情,写下这篇文章。如何用注解来规避那些各种验证而引发的一大堆if判断。

 图片

首先我们建立一个简单的注解。里面包含空验证以及格式的正则。

@Retention(RetentionPolicy.RUNTIME)   在这个注解标记下。当前注解将可以被反射读取到。

 

@Target(ElementType.FIELD)  代表当前注解用于字段。

 

如果是spring项目或者web项目,可以用AOP来实现自动验参。笔者近日为了方便,直接在上次的那个APP架构上来进行处理。

 

那么验证将放在API接口的入口。

 

 图片

 

 

调整之后

 

图片

 

 

图片

 

然后我们来看下效果

图片

 

如下是当前过滤器的全部代码。

package com.app.server.filter;



import java.io.IOException;

import java.io.PrintWriter;

import java.lang.annotation.Annotation;

import java.lang.reflect.Method;

import java.util.List;



import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;



import com.app.server.annotation.ParamCheck;

import com.app.server.annotation.ReqType;

import com.app.server.api.base.TurboApi;

import com.app.server.enm.APIRespEnum;

import com.app.server.entity.BeanFieldEntity;

import com.app.server.util.GsonUtil;

import com.app.server.util.PropertUtil;

import com.app.server.util.SpringContextHelper;

import com.app.server.util.StringUtils;

import com.app.server.vo.base.BaseReqVO;



public class APIFilter implements Filter {

private static final String apiFunctionName="execute";

@Override

public void doFilter(ServletRequest servReq, ServletResponse servResp,

FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) servReq;

HttpServletResponse response = (HttpServletResponse) servResp;

response.setCharacterEncoding("utf-8");

String apiName = request.getHeader("APIName");

System.out.println("请求接口名:" + apiName);

TurboApi api = (TurboApi) SpringContextHelper.getBean(apiName);

if (api == null) {

writeEnum(response,APIRespEnum.API_NOT_FOUND);

return;

}

try {

//获得接口方法所需ReqVO类型

Class<?> reqVoCla=getAPIParaType(api);

//接受客户端json参数

String json=GsonUtil.getJsonContent(request);

System.out.println("请求参数:"+json);

//获得请求对象

BaseReqVO reqVO=(BaseReqVO) GsonUtil.jsonToObject(json, reqVoCla);

//进行参数验证

APIRespEnum errEnum=checkPara(reqVO);

if(!StringUtils.isNullOrEmpty(errEnum)){

writeEnum(response,errEnum);

return;

}

//执行api方法

Object obj=api.execute(request, reqVO);

//响应json结果

String context=GsonUtil.objectToJson(obj);

writeMsg(response,context);

return;

} catch (Exception e) {

// TODO: handle exception

}

return;

}

private Class<?> getAPIParaType(TurboApi api){

Method method=PropertUtil.getMethod(api.getClass(), apiFunctionName, HttpServletRequest.class,BaseReqVO.class);

Annotation[][] annoss=method.getParameterAnnotations();

for (Annotation[] annos:annoss) {

for (Annotation anno:annos) {

if(anno instanceof ReqType){

return ((ReqType) anno).value();

}

}

}

return null;

}

private APIRespEnum checkPara(BaseReqVO reqVO){

List<BeanFieldEntity>  entitys=PropertUtil.getBeanFields(reqVO);

for (BeanFieldEntity entity:entitys) {

ParamCheck check= entity.getSourceField().getAnnotation(ParamCheck.class);

if(!check.allowNull()){

Object obj=PropertUtil.getFieldValue(reqVO, entity.getFieldName());

String msg=check.errorMsg();

if(StringUtils.isNullOrEmpty(obj)){

return getParaErrEnum(APIRespEnum.PARA_IS_NULL,entity.getFieldName(),msg);

}

if(!StringUtils.isNullOrEmpty(check.format())){

if(!StringUtils.isMatcher(obj.toString(), check.format())){

return getParaErrEnum(APIRespEnum.PARA_ERROR,entity.getFieldName(),msg);

}

}

if(!StringUtils.isNullOrEmpty(check.orNulls())){

List<Object> values=PropertUtil.getFieldValues(reqVO, check.orNulls());

if(!StringUtils.isAllNull(values)){

return getParaErrEnum(APIRespEnum.PARAS_IS_NULL,entity.getFieldName()+":"+check.orNulls().toString(),msg);

}

}

}

}

return null;

}

private APIRespEnum getParaErrEnum(APIRespEnum enm,String fieldName,String msg){

APIRespEnum currNum=enm;

if(!StringUtils.isNullOrEmpty(msg)){

currNum.setMsg(msg);

}

currNum.setMsg(currNum.getMsg()+":"+fieldName);

return currNum;

}

private void writeEnum(HttpServletResponse response,APIRespEnum msgEnum) {

String context = msgEnum.toJson();

writeMsg(response,context);

}

private void writeMsg(HttpServletResponse response,String context) {

try {

PrintWriter out = response.getWriter();

out.print(context);

out.flush();

out.close();



} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void init(FilterConfig arg0) throws ServletException {

}

@Override

public void destroy() {

}

}

 

 

JAVA技术交流群:218481849

© 著作权归作者所有

Coody

Coody

粉丝 62
博文 24
码字总数 27571
作品 5
广州
后端工程师
私信 提问
加载中

评论(0)

一个O2O后端架构问题咨询

一个后端架构问题咨询 业务: O2O,采购方通过App向供应商申请供货,供应商审核通过后 , 采购方可在App上进入该供货商的店铺中进行下单。 后端 仅负责提供Rest Api,前端调用后端提供的接口来...

zgw06629
2015/11/01
202
1
前后端分离后台api接口框架探索

前言   很久没写文章了,今天有时间,把自己一直以来想说的,写出来,算是一种总结吧! 这篇文章主要说前后端分离模式下(也包括app开发),自己对后台框架和与前端交互的一些理解和看法。 ...

osc_6odm1qf4
04/16
10
0
app后端设计--总目录

做了3年app相关的系统架构,api设计,先后在3个创业公司中工作,经历过手机网页端,android客户端,iphone客户端,现就职于app云后端平台bmob(想了解bmob点击这里)。其中的乐与苦,得与失,...

云栖希望。
2017/12/04
0
0
由浅入深一个Demo带你认识Restful风格的架构

java作为一门后端语言,其厉害之处在于web,大家比较熟知的各种网络应用,java都能做,那么在这个移动优先的时代,如何继续发挥java的强大之处呢? 通常是让java作为一个app的服务端,为app客...

osc_28hs2gg6
2019/05/09
2
0
互联网架构,为啥要前后端分离?

通用业务服务化之后,系统的典型后端结构如上: web-server通过RPC接口,从通用业务服务获取数据 biz-service通过RPC接口,从多个基础数据service获取数据 基础数据service通过DAO,从独立d...

xqtesting
2017/12/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mongodb服务挂了重启日志报错Out of memory

1、问题描述: 今天突然PHP同事给我说预发布的mongo挂了,我上去看了一下日志显示: 原因: 同事说他建了个索引,然后mongo就挂了,由于mongodb的重建索引的时候,吃掉所有内存,导致mongodb...

osc_b67rw1ne
6分钟前
8
0
数据库实验-数据查询语言

(1)查询学生的基本信息; select * from S; (2)查询“CS”系学生的基本信息; select * from S where Sdept =’CS’; (3)查询“CS”系学生年龄不在19到21之间的学生的学号、姓名; se...

osc_9q6q9p40
7分钟前
3
0
【赵强老师】Weblogic域和域的组成

一、什么是Weblogic WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于Java EE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和...

osc_52r4y6wv
9分钟前
11
0
ros gazebo it says it's incompatible with that RT

环境说明 ubuntu 16.04 osrf/ros:kinetic-desktop-full-xenial gazebo 7.0.0 问题 gzserver: /build/ogre-1.9-mqY1wq/ogre-1.9-1.9.0+dfsg1/OgreMain/src/OgreRenderSystem.cpp:546: virtual......

osc_7nzqlmki
10分钟前
6
0
mysqldump导出数据库报mysqldump: Couldn't execute 'SELECT

mysqldump命令:   导出数据库:mysqldump -h ip -u root -p dbname > db.sql;   导出数据库中的某个表:mysqldump -h ip -u root -p dbname tablename > tablename.sql; 错误提示:   ......

osc_gxvh47u5
11分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部