springboot 自定义注解开发

1、简单介绍注解

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。


2、举例说明如何定义注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
    String value() default "";
}

@Target:用于描述注解的使用范围(注解可以用在什么地方)

ElementType.TYPE:类、接口(包括注解类型) 或enum声明。

@Retention:注解的生命周期,用于表示该注解会在什么时期保留。

RetentionPolicy.RUNTIME:运行时保留,这样就可以通过反射获得了。

@Documented:表示该注解会被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。

3、自定义开发注解

前提需求:在公众号中上传图片时,图片上传到微信的服务器中,并且会返回mediaId。这时我们拿到mediaid到微信服务器中将图片下载并上传到自己的服务器中。例如:当前端同学传给后端用户头像时候,我们希望进入controller时候,这些流程全部已经实现。在业务层只是单纯的执行所需要的业务逻辑。
实现内容:前端 cheadimg=mediaid【微信给的图片id】–> 进入controller时,cheadimg=http://zhang.com/001.jpg【自己服务器中的图片地址】
废话不多说了,直接贴上相关代码:
a:自定义一个注解

/**
 * 设置微信图片注解
 * Retention:保留至运行时,通过反射去获取注解信息。
 * Target:方法级别的
 * Created by zhang on 2018/5/10.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface SetWeChatImg {
    String value() default "";
}

b:添加拦截器,拦截每个方法、类中是否添加注解@SetWeChatImg

/**
 * 在WebMvcConfigurerAdapter里添加拦截器
 * Created by zhang on 2018/5/10.
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    /**
     * 在Spring添加拦截器之前先自己创建一下这个WeChatImgInterceptor
     */
    @Bean
    public WeChatImgInterceptor weChatImgInterceptor() {
        return new WeChatImgInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 多个拦截器组成一个拦截器链
        // addPathPatterns 用于添加拦截规则
        registry.addInterceptor(weChatImgInterceptor()).addPathPatterns("/control/loan/wechatimg/*");
        super.addInterceptors(registry);
    }
}
/**
 * Created by zhang on 2018/5/10.
 */
@Component
public class WeChatImgInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    WeChatImgUtil util;

    /**
     * 微信图片
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        SetWeChatImg setWeChatImg = method.getAnnotation(SetWeChatImg.class);
        if (setWeChatImg != null) {
            ParameterRequestWrapper requestWrapper = (ParameterRequestWrapper) request;
            util.wehatImg(requestWrapper);
        }
        return true;
    }
}

c:实现功能的一个util类

/**
 * 微信图片从服务器上获取并下载到自己服务器
 * Created by zhang on 2018/5/8.
 */
@Component
public class WeChatImgUtil {

    private static Logger logger = LoggerFactory.getLogger(WeChatImgUtil.class);

    public static final String APPNAME = "zhang";

    @Autowired
    Environment evn;

    @Autowired
    MemCachedClient memCachedClient;

    @Autowired
    RedisTemplate redisTemplate;

    public void wehatImg(ParameterRequestWrapper requestWrapper) throws Exception {
        logger.info("wehatImg:上传微信图片开始---------");
        LocalDate today = LocalDate.now();
        int year = today.getYear();
        int month = today.getMonthValue();
        int date = today.getDayOfMonth();
        //dir =2018/5/8/
        String dir = new StringBuilder().append(year).append(File.separator).append(month).append(File.separator).append(date).append("/").toString();
        logger.info("dir={}", dir);
        Map map = new HashMap<>();
        map.put("cheadimg", requestWrapper.getParameter("cheadimg"));
        map.put("cidcardface", requestWrapper.getParameter("cidcardface"));
        map.put("cidcardback", requestWrapper.getParameter("cidcardback"));
        Set> entries = map.entrySet();
        Iterator> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = iterator.next();
            if (entry.getValue() != null) {
                String mediaId = entry.getValue().trim();
                if (mediaId.indexOf("http:") < 0) {
                    //下载图片都用loan的appId
                    String imgName = downloadImg(mediaId, dir, entry.getKey());
                    if (imgName != null) {
                        requestWrapper.setParameter(entry.getKey(), imgName);
                    } else {
                        requestWrapper.setParameter("errcode", "-1");
                        requestWrapper.setParameter("errdesc","图片上传失败");
                    }
                    logger.info("imgName---------" + imgName);
                }

            }
        }
    }

    /**
     * 根据mediaId下载图片,并返回图片名称
     *
     * @param mediaId
     * @param dirStr
     * @throws IOException
     */

    public String downloadImg(String mediaId, String dirStr, String fileType) throws IOException {
        String uploadPath = "/Users/zhang/export/img/";
        String downLoadPath = "/Users/zhang/export/img/";
        logger.info("uploadPath = {}, downLoadPath = {}", uploadPath, downLoadPath);
        File dir = new File(uploadPath, dirStr);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        String imageName = UUID.randomUUID().toString() + ".jpg";
        String url = new StringBuilder("http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=")
                .append(getAccess_token())
                .append("&media_id=")
                .append(mediaId)
                .toString();
        System.out.println("图片下载地址:" + url);
        DataInputStream dataInputStream = new DataInputStream(new URL(url).openStream());
        FileOutputStream fileOutputStream = new FileOutputStream(new File(dir, imageName));

        byte[] buffer = new byte[1024];
        int length;
        int i = 0;
        while ((length = dataInputStream.read(buffer)) > 0) {
            i++;
            //先读取,判断大小,是否超过1k,小于1k为json错误
            if (i == 1 && length < buffer.length) {
                String respStr = new String(buffer, Charset.forName("UTF-8"));
                logger.error("从微信端下载图片失败:" + respStr);
                return null;
            }
            fileOutputStream.write(buffer, 0, length);
        }
        dataInputStream.close();
        fileOutputStream.close();
        return downLoadPath + dirStr + imageName;
    }

    /**
     * 获取微信token【先从memcached中获取,如果为null,redis中获取】
     *
     * @return
     */
    public String getAccess_token() {
        String key = APPNAME + "_access_token";
        String access_token = (String) memCachedClient.get(key);
        if (null == access_token) {
            access_token = redisTemplate.opsForValue().get(key);
            if (null == access_token) {
                logger.error("error报警:memcached和redis中均没有获取到微信token");
            }
        }
        return access_token;
    }
}

d:模拟测试

    @RequestMapping("/control/loan/wechatimg/test")
    @SetWeChatImg
    public JSONObject annotationTest(LendUserBean bean) {
        System.out.println("我是注解测试~~~~~");
        return null;
    }

springboot 自定义注解开发_第1张图片

你可能感兴趣的:(注解开发)