public void createImage(HttpServletResponse resp, HttpServletRequest request,String xcode) throws IOException { TraceLoggerUtil.info("執行微信端圖片驗證碼接口請求參數:xcode{}",xcode); switch (random.nextInt(5)) { case 0: cs.setFilterFactory(new CurvesRippleFilterFactory(cs.getColorFactory())); break; case 1: cs.setFilterFactory(new MarbleRippleFilterFactory()); break; case 2: cs.setFilterFactory(new DoubleRippleFilterFactory()); break; case 3: cs.setFilterFactory(new WobbleRippleFilterFactory()); break; case 4: cs.setFilterFactory(new DiffuseRippleFilterFactory()); break; } HttpSession session = request.getSession(false); if (session == null) { session = request.getSession(); } if (ChkUtil.isEmpty(xcode)) { return; } setResponseHeaders(resp); String token = EncoderHelper.getChallangeAndWriteImage(cs, "png", resp.getOutputStream()); redisService.setex(xcode, token, 5*60); session.setAttribute(PubVariable.VERIFICATION_CODE_SESSION, token); } protected void setResponseHeaders(HttpServletResponse response) { response.setContentType("image/png"); response.setHeader("Cache-Control", "no-cache, no-store"); response.setHeader("Pragma", "no-cache"); long time = System.currentTimeMillis(); response.setDateHeader("Last-Modified", time); response.setDateHeader("Date", time); response.setDateHeader("Expires", time); }
今天遇到一個需求須要將生成驗證碼的接口修改成能夠返回狀態的接口。以前的代碼是以流的形式直接返回後臺,返回值爲void。使用的是com.github.bingoohuang的jar包。前端
可是出現問題是如今須要返回帶有狀態的json串,而後將圖片信息放在參數內,給前端在status爲200的時候才展現圖片信息。這時候能夠將隨機驗證碼圖片進行Base64編碼以後前端使用。git
如下貼代碼:github
public String createImage(HttpServletResponse resp, HttpServletRequest request
,String xcode,String phone,String from ) {
JSONObject resultObject = new JSONObject();
TraceLoggerUtil.info("執行微信端圖片驗證碼接口請求參數:xcode{},phone{},from{}",xcode,phone,from);
try{
/**
* from =1 的時候須要判斷當前手機號是否存在 若是存在直接返回300 手機號已存在
*/
if (!ChkUtil.isEmpty(from) && "1".equals(from)) {
JSONObject phoneJson = JSONObject.parseObject(bgCustomerService.getCustomer(phone));
if (phoneJson.get(com.zw.rule.util.weChatUtil.consts.MsgConsts.RESPONSE_CODE).equals(com.zw.rule.util.weChatUtil.consts.MsgConsts.WECHAT_ERRO_CODE)) {
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_STATUS, com.zw.base.util.MsgConsts.WECHAT_ERROR_STATUS_CODE);
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_MESSAGE, "手機號已存在");
return resultObject.toString();
}
}
/**
* from =2 的時候須要判斷當前手機號是否存在 若是存在直接返回300 手機號不存在
*/
if (!ChkUtil.isEmpty(phone) && "2".equals(phone)) {
JSONObject phoneJson = JSONObject.parseObject(bgCustomerService.getCustomer(phone));
if (phoneJson.get(com.zw.rule.util.weChatUtil.consts.MsgConsts.RESPONSE_CODE).equals(com.zw.rule.util.weChatUtil.consts.MsgConsts.SUCCESS_CODE)) {
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_STATUS, com.zw.base.util.MsgConsts.WECHAT_ERROR_STATUS_CODE);
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_MESSAGE, "手機號不存在");
return resultObject.toString();
}
}
// 禁止圖像緩存,使得單擊驗證碼能夠刷新驗證碼圖片
resp.setHeader("Pragma", "nocache");
resp.setHeader("Cache-Control", "no-cache");
resp.setDateHeader("Expires", 0);
resp.setContentType("image/jpeg");
resp.setHeader("Access-Control-Allow-Origin", "*");
BufferedImage bim = new BufferedImage(100, 40,
BufferedImage.TYPE_INT_RGB);
Font f = new Font("宋體",Font.BOLD ,20);
Graphics2D gc = bim.createGraphics();
//設置字體
gc.setFont(f);
// 設置圖片填充顏色
gc.setColor(Color.yellow);
gc.fillRect(0, 0, 100, 40);
// 設置邊框顏色
gc.setColor(Color.pink);
gc.drawRect(0, 0, 99, 39);
// 產生4位隨機數
Random rand = new Random();
StringBuffer sb = new StringBuffer();
// 設置干擾線顏色
gc.setColor(Color.cyan);
for (int j = 0; j < 30; j++) {
int x = rand.nextInt(99);
int y = rand.nextInt(39);
int x1 = rand.nextInt(6);
int y1 = rand.nextInt(6);
// 往圖片裏面畫干擾線
gc.drawLine(x, y, x + x1, y + y1);
}
for (int i = 0; i < 4; i++) {
int m = rand.nextInt(9);
// 將生成的數字寫入到圖片中去,int轉成string
String str = String.valueOf(m);
// 設置字體顏色
gc.setColor(Color.RED);
gc.drawString(str, i * 20 + 20, 30);
sb.append(m);
}
// 將stringbuffer轉成string
String sb1 = String.valueOf(sb);
redisService.setex(xcode, sb1, 5*60);
// 將圖片以流的形式輸出
ServletOutputStream sos = resp.getOutputStream();
//ImageIO.write(bim, "jpg", sos);
// 建立編碼對象
Base64.Encoder base64 = Base64.getEncoder();
// 建立字符流
ByteArrayOutputStream bs = new ByteArrayOutputStream();
// 寫入字符流
ImageIO.write(bim, "jpg", bs);
// 轉碼成字符串
String imgsrc = base64.encodeToString(bs.toByteArray());
resultObject.put("imgsrc",imgsrc);
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_STATUS, com.zw.base.util.MsgConsts.WECHAT_SUCCESS_STATUS_CODE);
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_MESSAGE, com.zw.base.util.MsgConsts.WECHAT_MESSAGE_SUCCESS);
}catch (Exception e){
TraceLoggerUtil.error(e.getMessage(),e);
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_STATUS, com.zw.base.util.MsgConsts.WECHAT_ERROR_STATUS_CODE);
resultObject.put(com.zw.base.util.MsgConsts.WECHAT_RESPONSE_MESSAGE, com.zw.base.util.MsgConsts.SYS_EXCEPTION);
return resultObject.toString();
}
return resultObject.toString();
}
如下代碼有變動點:ajax
1.resp.setHeader("Access-Control-Allow-Origin", "*"); 這是因爲前端使用ajax訪問的時候跨域了,設置這個以後就不會跨域訪問redis
2.Font f = new Font("宋體",Font.BOLD ,20); gc.setFont(f); 這裏是因爲字體偏小,因此調大字體爲宋體20號json
3.gc.fillRect(0, 0, 100, 40); gc.drawRect(0, 0, 99, 39); int x = rand.nextInt(99); int y = rand.nextInt(39);跨域
我的理解這些數字都和最後返回的圖片有關。返回前端圖片爲100*40那麼 drawRect 的最後兩個數字爲 100-1 40-1 int x爲100-1 int y 爲40 -1xcode
4.gc.drawString(str, i * 20 + 20, 30); 這個根據圖片的寬和高計算,最終數字的位置爲20,40,60,80 高固定在30 緩存
以上這些須要根據前端須要自行調節。微信
前端使用方式爲:
<img src=」data:image/jpg;base64,imgcode」> imgcode 就是返回回去的base64位的imgsrc
點擊後動態的賦值便可。