springboot 自定義註解開發
阿新 • • 發佈:2019-01-25
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;
}