springMVC框架下如何实现移动端接口调用——代码实例

        上一篇博客中已经简单的整理了移动端调用PC端接口的实现流程,这其中涉及到springMVC拦截器的使用。下面通代码对应上篇博客中的流程简介看一下具体是如何实现的。首先定义一个拦截器,需要实现HandlerInterceptor接口,这个接口有三个方法,在这里的作用是验证用户是否登录,所用只用preHandle这个方法就可以完成。首先需要建立两个类,InDto和OutDto分别是信息接收实体和信息反馈实体。


InDto:主要是用来接收移动端URL请求的参数包括请求的controller、方法、参数。

<span style="font-size:18px;">/** 
 * <p>Title:InDto</p>
 * Description:参数接收实体类 
 */
public class InDto {
	/**
	 * 版本号
	 *一般为固定的,主要是为了和Action进行凭借识别对应的controller
	 */
	private String version;
	/**
	 * 方法包名
	 */
	private String action;
	/**
	 * 方法名
	 */
	private String method;	
	/**
	 * 时间戳
	 */
	private String timeStamp;	
	/**
	 * 请求参数
	 */
	private String req;
	/**
	 * 接口请求request
	 */
	private HttpServletRequest request;
	/**
	 * 接口请求response
	 */
	private HttpServletResponse response;
	/**
	 * 注入
	 */
	private Object dao;

	public String getVersion() {
		return version;
	}
	public void setVersion(String version) {
		this.version = version;
	}
	public String getAction() {
		return action;
	}
	public void setAction(String action) {
		this.action = action;
	}
	public String getMethod() {
		return method;
	}
	public void setMethod(String method) {
		this.method = method;
	}
	public String getTimeStamp() {
		return timeStamp;
	}
	public void setTimeStamp(String timeStamp) {
		this.timeStamp = timeStamp;
	}
	
	public String getReq() {
		return req;
	}
	public void setReq(String req) {
		this.req = req;
	}
	public Object getDao() {
		return dao;
	}
	public void setDao(Object dao) {
		this.dao = dao;
	}
	public HttpServletRequest getRequest() {
		return request;
	}
	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}	
	public HttpServletResponse getResponse() {
		return response;
	}
	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	//构造函数
	public InDto(Map<String,String[]> map) throws IOException{
		this.version=map.get("Version")!=null?map.get("Version")[0]:"";
		this.action=map.get("Action")!=null?map.get("Action")[0]:"";		
		this.method=map.get("Method")!=null?map.get("Method")[0]:"";				
		this.timeStamp=map.get("TimeStamp")!=null?map.get("TimeStamp")[0]:"";
		this.req=map.get("Req")!=null?map.get("Req")[0]:"";

	}
}
</span>


OutDto:主要用来返回约定的编码,方便移动端确定请求成功、失败、或者服务器请求失败。

<span style="font-size:18px;">/**
 * <p>Title:OutDto</p>
 * Description: 信息反馈实体类
*/
public class OutDto {
	/**
	 * 成功
	 */
	public static final String STATUS_SUCCESS="100";  
	/**
	 * 失败
	 */
	public static final String STATUS_FAIL="200";  
	/**
	 * 服务端异常
	 */
	public static final String STATUS_EXCEPTION="300";  
	
	/**
	 * 代码标识
	 */
	private String status;
	/**
	 * 信息
	 */
	private String msg;
	/**
	 * 返回数据
	 */
	private Object data;
	
	
	public String getStatus() {
		return status;
	}
	public void setStatus(String status) {
		this.status = status;
	}
	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 void setStatusFail() {
		this.status = STATUS_FAIL;
	}
	/**
	 * @描述 设置失败状态和消息
	 */
	public void setStatusFail(String msg) {
		this.status = STATUS_FAIL;
		this.msg=msg;
	}
	
	
	/**
	 * @描述 设置成功状态
	 */
	public void setStatusSuccess() {
		this.status = STATUS_SUCCESS;
	}
	/**
	 * @描述 设置成功状态并插入data数据
	 * @author quzf
	 */
	public void setStatusSuccess(Object data,String msg) {
		this.status = STATUS_SUCCESS;
		this.data=data;
		this.msg=msg;
	}
	/**
	 * @描述 设置成功状态并插入data数据
	 */
	public void setStatusSuccess(String msg) {
		this.status = STATUS_SUCCESS;
		this.msg=msg;
		this.data="";
	}	
}
</span>


移动端约定的请求接口的URL:

http://localhost:8080/test/Service/dataSync.do?&Version=1.0&Action=login&Method=Login &TimeStamp=10000&Req={"params":{
    "userName": "admin",
    "userPwd ": "123456"
   }
}


编写一个拦截器实现接口HandlerInterceptor

<span style="font-size:18px;">/**
*
*拦截器
*/
public class DataSyncInterceptor   implements HandlerInterceptor {
	
	@Autowired
	private OrganService organService;
	
	/**
	 * @描述 验证用户名密码是否正确
	 */
	public OutDto testLegal(HttpServletRequest request) throws Exception {
		//实例化一个InDto,同时获得了客户端传来的信息
InDto inDto=new InDto(request.getParameterMap());
		JSONObject reqJSON = JSON.parseObject(inDto.getReq());
		String action = inDto.getAction();//获取到请求的Action
		OutDto outDto=new OutDto();
	if(action.equals("login")){//如果是登录进行验证	
String userName = reqJSON.getString("userName");
			String userPwd = reqJSON.getString("userPwd");
			User user = organService.login(userName, userPwd);
			
			if(user==null){
				outDto.setStatusFail();
				outDto.setMsg("用户名或密码不正确!");
			}else{
				outDto.setStatusSuccess();
			}
			return outDto;
		}
	}
	
		@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object o) throws Exception {
		//请求参数注入InDto
		OutDto outDto=new OutDto();
		try {
			InDto inDto=new InDto(request.getParameterMap());
			//设置验证结果,先不走验证非法,直接返回成功
			outDto = testLegal(request);
			//参数验证结果成功后,执行下面的拦截器
			if(OutDto.STATUS_SUCCESS.equals(outDto.getStatus())){
				return true;
			}else{
				response.setCharacterEncoding("UTF-8");
				PrintWriter out = response.getWriter(); 
				out.print(JsonUtil.object2json(outDto));
				out.close();  
	          return false;
			}
		} catch (Exception e) {
			 response.setCharacterEncoding("UTF-8");
			 outDto.setStatus(OutDto.STATUS_EXCEPTION);//异常时
			 PrintWriter out = response.getWriter(); 
			 out.print(JsonUtil.object2json(outDto));  
			 e.printStackTrace();
			 out.close();  
            return false;
		}
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2, ModelAndView arg3) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void afterCompletion(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		
	}
}
</span>


          拦截器配置到mvc的配置文件中:

<mvc:interceptors>
        <mvc:interceptor>
        	<!-- //映射路径后缀名 -->
            <mvc:mapping path="/Service/*"/>
            <!--//自定义拦截器 -->
            <bean class="interceptor.DataSyncInterceptor"/>
        </mvc:interceptor>
</mvc:interceptors>

        拦截器走完如果用户验证通过后preHandle方法返回true,由于没有配置其他的拦截器就会根据请求的URL开始调用对应的controller。请求的URL中有“http://localhost:1080/test/Service/dataSync.do”   所以会根据URL找到Service这个controller中的dataSync方法。

<span style="font-size:18px;">/**
 * <p>Title:ServiceController</p>
 * Description: 移动端接口入口
 */
@Controller
@RequestMapping("Service")
public class ServiceController{
	
	 @RequestMapping({"/dataSync"})
	 @ResponseBody
	public void dataSync(HttpServletRequest request, HttpServletResponse response) {
		 OutDto outDto = new OutDto();
		try {
			 InDto inDto=new InDto(request.getParameterMap());
			 inDto.setRequest(request);
			 inDto.setResponse(response);			
			 String method = inDto.getMethod();			 
			if(StringUtils.isBlank(method)){
				method=AtcConstant.getAtcClassMethod();
			}			
			//依据action和method,然后读取配置中的类反射执行该class
			Object bean = SpringHelper.getBean(inDto.getAction()+inDto.getVersion());		
			outDto=(OutDto) ReflectUtil.invoke(bean,method, inDto,outDto);
		} catch (Exception e) {
			outDto.setStatus(OutDto.STATUS_EXCEPTION);
			e.printStackTrace();
		}
		try {
			//返回的结构为字节流是调用,为移动端做附件下载时使用
			if ("返回流".equals(outDto.getMsg())) { 
				OutputStream outputStream=response.getOutputStream();
				InputStream is=new FileInputStream(outDto.getData().toString());
				byte b[] = new byte[1024];
				int len = -1;
				while ((len = is.read(b)) != -1)
					outputStream.write(b, 0, len);
				
				is.close();
				outputStream.close();
			}else { 	//非字节流结果返回时调用
				response.setCharacterEncoding("UTF-8");
				PrintWriter out = response.getWriter();
				out.print(JsonUtil.object2json(outDto));
				out.close();  
			}			
		} catch (IOException e) {
			e.printStackTrace();
		} 		
	}
}
</span>

        这个方法中的核心代码是:

String method = inDto.getMethod();

Object bean =SpringHelper.getBean(inDto.getAction()+inDto.getVersion());      

outDto=(OutDto)ReflectUtil.invoke(bean,method, inDto,outDto);


         根据请求的Action+Version 可以确定要调用的Controller,用ReflectUtil中的invoke方法,将得到的实体bean和要调用的方法名称作为参数传递就可以调用相应controller中的方法。以这次的登录为例Action=login;Version =1.0就会请求名为login1.0的Controller中的Login方法。在这个controller的方法中就可以写系统的业务逻辑代码。

 

小结:

         移动端调用接口的代码实现就是这样的,通过拦截器进行登录验证,使用invoke调用请求的controller中的方法。




  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值