美文网首页
java使用自定义注解+SpringMVC+拦截器实现简单的用户

java使用自定义注解+SpringMVC+拦截器实现简单的用户

作者: 柠檬冰块 | 来源:发表于2019-06-26 17:07 被阅读0次

    1。自定义注解

    @Documented //支持JavaDoc文档注释

    @Inherited // 表某个被标注的类型是被继承的

    @Target(ElementType.METHOD) //表明该注解对成员方法起作用

    @Retention(RetentionPolicy.RUNTIME) //在编译以后仍然起作用

    public @interface logRecord {

    /**

    * @Description: 是否记录日志

    * @return: String

    * @author: fss

    */

    String validate() default AccessLoggingCode.CHECK_API;

    /**

    * @Description: 操作类型

    * @return: String

    * @author: fss

    */

    String operation() default AccessLoggingCode.SELECT;

    /**

    * @Description: 操作模块

    * @return: String

    * @author: fss

    */

    String operationModule() default "默认操作模块";

    /**

    * @Description: 操作备注

    * @return: String

    * @author: fss

    */

    String remark() default "默认备注";

    /**

    * @Description: 操作平台

    * @return: String

    * @author: fss

    */

    String operationTerrace() default AccessLoggingCode.savingAPP;

    }

    2。controller

    /**

    *

    * @Title: SupplierLogin 

    * @Description: app端运营商登录

    * @param: @param response

    * @param: @param request

    * @param: @return     

    * @return: Map<String,Object>

    * @author: FSS   

    * @throws

    */

    @ResponseBody

    @DataSourceAuth(validate=DatasourceConfig.dataSourceA)

    @PowerAuth(validate=RestPowerAPIcontent.NORMAL_API)

    @logRecord(operation=AccessLoggingCode.LOGIN ,operationTerrace = AccessLoggingCode.operatorAPP , operationModule = "app端运营商登录" , remark =AccessLoggingCode.LOGIN)

    @RequestMapping(value="/v1/Amd/OperatorLogin/login",method ={RequestMethod.POST},produces="application/json;charset=utf-8")

    public Map<String,Object> userLoginaes(@RequestBody Map<String,String> map){

    return operatorMemberService.operatorLoginingApp(map);

    }

    3.在spring.xml配置文件来构建拦截器(xxxx包名)

    <!-- 客户端访问日志拦截器 -->

      <mvc:interceptor>

        <mvc:mapping path="/app/**" />

    <mvc:mapping path="/rest/**" />

    <mvc:mapping path="/test/**" />

    <bean class="com.xxxx.filter.logRecordInterceptor"></bean>

      </mvc:interceptor>

    4.创建上面配置的拦截器, 来继承HandlerInteceptorAdaptor 或者实现 HandlerInteceptor 接口.这里集成 HandlerInteceptorAdaptor

    public class logRecordInterceptor extends HandlerInterceptorAdapter {

    @Autowired

    private UserAccessLoggingDao useraccessLoggingDao;

    /**

    * 在拦截器中通过ContentCachingResponseWrapper获取HttpServletResponse响应体中的数据

    * @param response

    * @return

    * @throws IOException

    * @author: fss

    */

    public static Map<String, Object> readPostJsonData(HttpServletResponse response) throws IOException {

            if (response instanceof ContentCachingResponseWrapper) {

            /*response.setCharacterEncoding("UTF-8"); 

        response.setHeader("Content-Type", "text/html;charset=UTF-8");*/

            ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response;

                int contentLenth = ((ContentCachingResponseWrapper) response).getContentSize();

                if (contentLenth <= 0) {

                    return null;

                }

                byte[] bytes = new byte[contentLenth];

                InputStream is = responseWrapper.getContentInputStream();

                for (int index = 0; index < contentLenth; index++) {

                    int value = is.read();

                    if (value == -1) {

    //                is.reset();

                        break;

                    }

                    bytes[index] = (byte) value;

                }

                //responseWrapper.getContentAsByteArray();//这里是为了测试

                String data = new String(bytes);

                //System.out.println("http util .........data:" + data);

                Map<String, Object> map = MapUtils.stringToMap(data);

                return map;

            }

            return null;

        }

    @Override

    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {

    return super.preHandle(request, response, handler);

    }

    // \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔),

    // 字符串在编译时会被转码一次,所以是 "\\b"

    // \B 是单词内部逻辑间隔(连着的两个字母字符之间的逻辑上的间隔)

    static String phoneReg = "\\b(ip(hone|od)|android|opera m(ob|in)i" + "|windows (phone|ce)|blackberry" + "|s(ymbian|eries60|amsung)|p(laybook|alm|rofile/midp"

    + "|laystation portable)|nokia|fennec|htc[-_]" + "|mobile|up.browser|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

    static String tableReg = "\\b(ipad|tablet|(Nexus 7)|up.browser" + "|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

    // 移动设备正则匹配:手机端、平板

    static Pattern phonePat = Pattern.compile(phoneReg, Pattern.CASE_INSENSITIVE);

    static Pattern tablePat = Pattern.compile(tableReg, Pattern.CASE_INSENSITIVE);

    /**

    * 获取设备名称

    * @param userAgent

    * @return

    */

    protected String getDeviceName(String userAgent) {

    if (null == userAgent) {

    userAgent = "";

    }

    // 匹配

    Matcher matcherPhone = phonePat.matcher(userAgent);

    Matcher matcherTable = tablePat.matcher(userAgent);

    if (matcherPhone.find()) {

    return matcherPhone.group();

    } else if (matcherTable.find()) {

    return matcherTable.group();

    } else {

    return "pc";

    }

    }

    /**

    * @Description: 返回处理

    * @return: String

    * @author: fss

    */

    @SuppressWarnings("unchecked")

    public void postHandle(HttpServletRequest request,

    HttpServletResponse response, Object handler,

    ModelAndView modelAndView) throws Exception {

    HandlerMethod hm =  (HandlerMethod) handler;

    logRecord record = hm.getMethodAnnotation(logRecord.class);

    if (record != null && record.validate().equals(AccessLoggingCode.CHECK_API)) {

      String operation = record.operation();//操作类型

      String businessLogic = record.operationModule();//操作模块

      String remark = record.remark();//备注

      String terrace = record.operationTerrace();//操作平台

      String url = request.getRequestURI();// 操作的URI

      String ip = CusAccessObjectUtil.getIpAddr(request);//访问ip

      String memberId="";

      String Agent = request.getHeader("User-Agent");//DEProvinceFuBao/1.89 (iPhone; iOS 12.2; Scale/3.00)

      String getDeviceName = getDeviceName(Agent);

      try {

        //取用户信息

        if(terrace.equals(AccessLoggingCode.savingAPP)||terrace.equals(AccessLoggingCode.supplierAPP)){

      String memberId1=request.getHeader("memberId");

      if(memberId1!=null&&!operation.equals(AccessLoggingCode.LOGIN)){//非登录从Header取用户信息

      memberId = memberId1;

      }else{ //从response取用户信息

      Map<String, Object> parametersAll = readPostJsonData(response);

      Map<String, Object> parameters = null;

      if(!MapUtils.mapIsAnyBlank(parametersAll, "data")){

      parameters =  (Map<String, Object>) parametersAll.get("data");

      if(!MapUtils.mapIsAnyBlank(parameters, "memberId")){

      memberId = parameters.get("memberId").toString();

      remark = "请求成功";

      }

      }else if(MapUtils.mapIsAnyBlank(parametersAll, "data")&&!MapUtils.mapIsAnyBlank(parametersAll, "code")&&!SuccessCodeConfigure.SUCCESS_CODE.equals(parametersAll.get("code"))){//访问失败

          String  errorMessage = "请求失败";

          if(!MapUtils.mapIsAnyBlank(parametersAll, "errorMessage")){

      errorMessage = parametersAll.get("errorMessage").toString();

      }

      remark = "errorMessage:"+errorMessage;

      }

      }

    }else if(terrace.equals(AccessLoggingCode.operatorAPP)){

    String cOperatorId=request.getHeader("cOperatorId");

    if(cOperatorId!=null&&!operation.equals(AccessLoggingCode.LOGIN)){//非登录从Header取用户信息

    memberId = cOperatorId;

    }else{//从response取用户信息

      Map<String, Object> parametersAll = readPostJsonData(response);

      Map<String, Object> parameters = null;

      if(!MapUtils.mapIsAnyBlank(parametersAll, "data")){

    parameters =  (Map<String, Object>) parametersAll.get("data");

    if(operation.equals(AccessLoggingCode.LOGIN)||operation.equals(AccessLoggingCode.LOGOUT)){

    if(!MapUtils.mapIsAnyBlank(parameters, "cOperatorId")){

        memberId = parameters.get("cOperatorId").toString();

    }

    }

      }else if(!MapUtils.mapIsAnyBlank(parametersAll, "code")&&!SuccessCodeConfigure.SUCCESS_CODE.equals(parametersAll.get("code"))){//访问失败

          String  errorMessage = "请求失败";

      if(!MapUtils.mapIsAnyBlank(parametersAll, "errorMessage")){

      errorMessage = parametersAll.get("errorMessage").toString();

      }

      remark = "errorMessage:"+errorMessage;

          }

        }

    }

    } catch (Exception e1) {

    // TODO Auto-generated catch block

    e1.printStackTrace();

    }

    //执行日志记录(此处根据自己业务逻辑写持久化代码)

    }

    super.postHandle(request, response, handler, modelAndView);

    }

    /**

    * 从request中获得参数Map,并返回可读的Map

    *

    * @param request

    * @return

    */

    @SuppressWarnings({ "unchecked", "rawtypes" })

    public static Map<String,Object> getParameterMap(HttpServletRequest request) {

        // 参数Map

        Map<String,Object> properties = request.getParameterMap();

        // 返回值Map

        Map<String,Object> returnMap = new HashMap();

        Iterator entries = properties.entrySet().iterator();

        Map.Entry entry;

        String name = "";

        String value = "";

        while (entries.hasNext()) {

            entry = (Map.Entry) entries.next();

            name = (String) entry.getKey();

            Object valueObj = entry.getValue();

            if(null == valueObj){

                value = "";

            }else if(valueObj instanceof String[]){

                String[] values = (String[])valueObj;

                for(int i=0;i<values.length;i++){

                    value = values[i] + ",";

                }

                value = value.substring(0, value.length()-1);

            }else{

                value = valueObj.toString();

            }

            returnMap.put(name, value);

        }

        return returnMap;

    }

    }

    其实利用拦截器还可以做简单的权限控制、一些敏感词过滤、简单的数据统计

    相关文章

      网友评论

          本文标题:java使用自定义注解+SpringMVC+拦截器实现简单的用户

          本文链接:https://www.haomeiwen.com/subject/sqthcctx.html