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

来源:互联网 发布:java api手机安卓版 编辑:程序博客网 时间:2024/06/08 08:36

        上一篇博客中已经简单的整理了移动端调用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 {@Autowiredprivate 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();//获取到请求的ActionOutDto 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;}}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object o) throws Exception {//请求参数注入InDtoOutDto 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;}}@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2, ModelAndView arg3) throws Exception {// TODO Auto-generated method stub}@Overridepublic 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"}) @ResponseBodypublic 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,然后读取配置中的类反射执行该classObject 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中的方法。




1 0
原创粉丝点击