1. 程式人生 > >springboot 自定義註解開發

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<String, String> 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<String, String> map = new HashMap<>();
        map.put("cheadimg", requestWrapper.getParameter("cheadimg"));
        map.put("cidcardface", requestWrapper.getParameter("cidcardface"));
        map.put("cidcardback", requestWrapper.getParameter("cidcardback"));
        Set<Map.Entry<String, String>> entries = map.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> 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;
    }

這裡寫圖片描述