探討Java驗(yàn)證碼制作(下篇)
接著上篇java驗(yàn)證碼制作(上篇)給大家介紹有關(guān)java驗(yàn)證碼的相關(guān)知識(shí)!
方法三:
用開(kāi)源組件Jcaptcha實(shí)現(xiàn),與Spring組合使用可產(chǎn)生多種形式的驗(yàn)證碼,JCaptcha 即為Java版本的 CAPTCHA 項(xiàng)目,其是一個(gè)開(kāi)源項(xiàng)目,支持生成圖形和聲音版的驗(yàn)證碼,在生成聲音版的驗(yàn)證碼時(shí),需要使用到 FreeTTS。而CAPTCHA 全稱 Completely Automated Public Turing Test to Tell Computers and Humans Apart,最早作為卡內(nèi)基梅隆大學(xué)的一個(gè)科研項(xiàng)目,用于生成一個(gè)人類(lèi)容易通過(guò)而計(jì)算機(jī)難以通過(guò)的測(cè)試,目前廣泛應(yīng)用于網(wǎng)絡(luò)應(yīng)用,用于阻止機(jī)器人發(fā)布垃圾信息。目前,JCaptcha 官方網(wǎng)站顯示有 2.0 版本,但二進(jìn)制版只有 1.0 版可供下載。
首先我們需準(zhǔn)備相應(yīng)的jar包
JCaptcha 項(xiàng)目在實(shí)現(xiàn)中,還引用了 commons-collections 和 commons-logging 兩個(gè)開(kāi)源項(xiàng)目,再加上 JCaptcha 本身的實(shí)現(xiàn),我們共需要三個(gè)包,具體信息如下:
jcaptcha-2.0-all.jarcommons-logging-1.1.1.jarcommons-collections-3.2.jar
其次我們看下面web.xml中的關(guān)鍵配置信息:除配置了Jcaptcha組件的具體class路徑外,還配置了SubmitActionServlet這個(gè)用于比對(duì)驗(yàn)證碼的servlet,并且都為二者做了映射,可理解為換了名字,分別為/jcaptcha.jpg和/submit.action調(diào)用組件或servlet時(shí)直接用這個(gè)映射名即可。
<servlet> <servlet-name>jcaptcha</servlet-name> <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class> </servlet> <servlet> <servlet-name>submit</servlet-name> <servlet-class>com.octo.captcha.module.servlet.image.sample.SubmitActionServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>jcaptcha</servlet-name> <url-pattern>/jcaptcha.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>submit</servlet-name> <url-pattern>/submit.action</url-pattern> </servlet-mapping>
web.xml
然后來(lái)看SubmitActionServlet怎么實(shí)現(xiàn):由于導(dǎo)入了jcaptcha的組件包,所以直接調(diào)用其中封裝好的方法SimpleImageCaptchaServlet.validateResponse(request, userCaptchaResponse)來(lái)判斷驗(yàn)證碼中的信息是否與提交的匹配,而不需要去考慮具體的實(shí)現(xiàn)過(guò)程。
public class SubmitActionServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userCaptchaResponse = request.getParameter("japtcha"); boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse(request, userCaptchaResponse); if (captchaPassed) response.getWriter().write("captcha passed"); else { response.getWriter().write("captcha failed"); } response.getWriter().write("<br/><a href='index.jsp'>Try again</a>"); } } SubmitActionServlet
最后我們看一下簡(jiǎn)單的前臺(tái)調(diào)用:
<html> <body> <h>Simple Captcha Servlet sample</h> <form action="submit.action" method="post"> <img src="jcaptcha.jpg" /> <input type="text" name="japtcha" value="" /> <input type="submit"/> </form> </body> </html>
實(shí)現(xiàn)圖例:
方法四:
用開(kāi)源組件kaptcha實(shí)現(xiàn),同樣使用kaptcha需要下載其jar組件包,kaptcha 是一個(gè)非常實(shí)用的驗(yàn)證碼生成工具。有了它,你可以生成各種樣式的驗(yàn)證碼,因?yàn)樗强膳渲玫?。kaptcha工作的原理是調(diào)用 com.google.code.kaptcha.servlet.KaptchaServlet(可以看出他是谷歌的一個(gè)開(kāi)源項(xiàng)目),生成一個(gè)圖片。同時(shí)將生成的驗(yàn)證碼字符串放到 HttpSession中。
使用kaptcha可以方便的配置:
驗(yàn)證碼的字體驗(yàn)證碼字體的大小驗(yàn)證碼字體的字體顏色驗(yàn)證碼內(nèi)容的范圍(數(shù)字,字母,中文漢字!)驗(yàn)證碼圖片的大小,邊框,邊框粗細(xì),邊框顏色驗(yàn)證碼的干擾線(可以自己繼承com.google.code.kaptcha.NoiseProducer寫(xiě)一個(gè)自定義的干擾線)驗(yàn)證碼的樣式(魚(yú)眼樣式、3D、普通模糊……當(dāng)然也可以繼承com.google.code.kaptcha.GimpyEngine自定義樣式)
……
對(duì)kaptcha的配置信息同樣的是放在了web.xml中:<init-param>標(biāo)簽中即初始化的配置信息
<servlet> <servlet-name>Kaptcha</servlet-name> <servlet-class> com.google.code.kaptcha.servlet.KaptchaServlet </servlet-class> <init-param> <description>圖片邊框,合法值:yes , no</description> <param-name>kaptcha.border</param-name> <param-value>yes</param-value> </init-param> <init-param> <description> 邊框顏色,合法值: r,g,b (and optional alpha) 或者 white,black,blue. </description> <param-name>kaptcha.border.color</param-name> <param-value>black</param-value> </init-param> <init-param> <description>邊框厚度,合法值:></description> <param-name>kaptcha.border.thickness</param-name> <param-value></param-value> </init-param> <init-param> <description>圖片寬 </description> <param-name>kaptcha.image.width</param-name> <param-value></param-value> </init-param> <init-param> <description>圖片高 </description> <param-name>kaptcha.image.height</param-name> <param-value></param-value> </init-param> <init-param> <description>圖片實(shí)現(xiàn)類(lèi)</description> <param-name>kaptcha.producer.impl</param-name> <param-value> com.google.code.kaptcha.impl.DefaultKaptcha </param-value> </init-param> <init-param> <description>文本實(shí)現(xiàn)類(lèi)</description> <param-name>kaptcha.textproducer.impl</param-name> <param-value> com.google.code.kaptcha.text.impl.DefaultTextCreator </param-value> </init-param> <init-param> <description>文本集合,驗(yàn)證碼值從此集合中獲取</description> <param-name>kaptcha.textproducer.char.string</param-name> <param-value></param-value> <!--<param-value>abcdegfynmnpwx</param-value>--> <!--<param-value>慕課網(wǎng)教程驗(yàn)證碼實(shí)例</param-value> --> </init-param> <init-param> <description>驗(yàn)證碼長(zhǎng)度 </description> <param-name>kaptcha.textproducer.char.length</param-name> <param-value></param-value> </init-param> <init-param> <description>字體 Arial, Courier</description> <param-name>kaptcha.textproducer.font.names</param-name> <param-value>Arial, Courier</param-value> </init-param> <init-param> <description>字體大小 px.</description> <param-name>kaptcha.textproducer.font.size</param-name> <param-value></param-value> </init-param> <init-param> <description> 字體顏色,合法值: r,g,b 或者 white,black,blue. </description> <param-name>kaptcha.textproducer.font.color</param-name> <param-value>black</param-value> </init-param> <init-param> <description>文字間隔 </description> <param-name>kaptcha.textproducer.char.space</param-name> <param-value></param-value> </init-param> <init-param> <description>干擾實(shí)現(xiàn)類(lèi)</description> <param-name>kaptcha.noise.impl</param-name> <param-value> <!-- com.google.code.kaptcha.impl.NoNoise --> com.google.code.kaptcha.impl.DefaultNoise </param-value> </init-param> <init-param> <description> 干擾顏色,合法值: r,g,b 或者 white,black,blue. </description> <param-name>kaptcha.noise.color</param-name> <param-value>black</param-value> </init-param> <init-param> <description> 圖片樣式: 水紋com.google.code.kaptcha.impl.WaterRipple 魚(yú)眼com.google.code.kaptcha.impl.FishEyeGimpy 陰影com.google.code.kaptcha.impl.ShadowGimpy </description> <param-name>kaptcha.obscurificator.impl</param-name> <param-value> com.google.code.kaptcha.impl.WaterRipple </param-value> </init-param> <init-param> <description>背景實(shí)現(xiàn)類(lèi)</description> <param-name>kaptcha.background.impl</param-name> <param-value> com.google.code.kaptcha.impl.DefaultBackground </param-value> </init-param> <init-param> <description>背景顏色漸變,開(kāi)始顏色</description> <param-name>kaptcha.background.clear.from</param-name> <param-value>green</param-value> </init-param> <init-param> <description>背景顏色漸變,結(jié)束顏色</description> <param-name>kaptcha.background.clear.to</param-name> <param-value>white</param-value> </init-param> <init-param> <description>文字渲染器</description> <param-name>kaptcha.word.impl</param-name> <param-value> com.google.code.kaptcha.text.impl.DefaultWordRenderer </param-value> </init-param> <init-param> <description> session中存放驗(yàn)證碼的key鍵 </description> <param-name>kaptcha.session.key</param-name> <param-value>KAPTCHA_SESSION_KEY</param-value> </init-param> <init-param> <description> The date the kaptcha is generated is put into the HttpSession. This is the key value for that item in the session. </description> <param-name>kaptcha.session.date</param-name> <param-value>KAPTCHA_SESSION_DATE</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Kaptcha</servlet-name> <url-pattern>/randomcode.jpg</url-pattern> </servlet-mapping>
前臺(tái)調(diào)用:驗(yàn)證碼圖片的路徑用了映射名randomcode.jpg,點(diǎn)擊事件onclick()調(diào)用了js函數(shù),js函數(shù)中同樣的用當(dāng)前時(shí)間使瀏覽器緩存失效來(lái)刷新驗(yàn)證碼圖片。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-"> <title>randomcode</title> <script type="text/javascript"> function changeR(node){ // 用于點(diǎn)擊時(shí)產(chǎn)生不同的驗(yàn)證碼 node.src = "randomcode.jpg?time="+new Date().getTime() ; } </script> </head> <body> <img alt="random" src="randomcode.jpg" onclick="changeR(this)" style="cursor: pointer;"> <form action="check.jsp"> <input type="text" name="r"> <input type="submit" value="s"> </form> </body> </html>
驗(yàn)證碼的比對(duì)check.jsp:通過(guò)(String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);得到驗(yàn)證碼圖片中字符串信息。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-"> <title>check</title> </head> <body> <% // 檢查是否是正確的驗(yàn)證碼 String k = (String) session .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); String str = request.getParameter("r"); if (k.equals(str)) out.print("true"); out.print(k + "---" + str); %> </body> </html>
實(shí)現(xiàn)圖例:
可以發(fā)現(xiàn)我們的驗(yàn)證碼變得越來(lái)越來(lái)豐富多彩了,但是還停留在一個(gè)只驗(yàn)證英文字母和數(shù)字的階段,那么還能不能玩點(diǎn)高端的呢,答案是肯定的。接下來(lái)我們來(lái)看一下中文驗(yàn)證碼和算術(shù)運(yùn)算驗(yàn)證碼怎么實(shí)現(xiàn)。都只需基于以上kaptcha的使用進(jìn)行修改即可。
中文驗(yàn)證碼的實(shí)現(xiàn):
首先我們找到kaptcha.jar包下有個(gè)DefaultTextCreator.class字節(jié)碼文件,顧名思義,他是來(lái)產(chǎn)生驗(yàn)證碼中文本的一個(gè)類(lèi),我們可以通過(guò)自己實(shí)現(xiàn)一個(gè)繼承于他的類(lèi),并通過(guò)配置來(lái)使用自己的實(shí)現(xiàn)類(lèi)來(lái)使驗(yàn)證碼中的文本變?yōu)橹形摹=?jīng)過(guò)如下反編譯后得到的類(lèi)我們可以看到其是那樣實(shí)現(xiàn)的,其中的getText()函數(shù)用于產(chǎn)生getConfig()配置器將要渲染的驗(yàn)證碼文本,所以我們只需繼承配置類(lèi)并實(shí)現(xiàn)文本產(chǎn)生接口后重寫(xiě)getText()方法即可。
public class DefaultTextCreator extends Configurable implements TextProducer { public String getText() { int length = getConfig().getTextProducerCharLength(); char[] chars = getConfig().getTextProducerCharString(); int randomContext = chars.length - ; Random rand = new Random(); StringBuffer text = new StringBuffer(); for (int i = ; i < length; i++) { text.append(chars[(rand.nextInt(randomContext) + )]); } return text.toString(); } }
如下為ChineseText.java的具體實(shí)現(xiàn):其中程序只執(zhí)行g(shù)etText()中的代碼,原來(lái)代碼寫(xiě)到了getText1()中,不執(zhí)行,大家可以做一個(gè)比較。
public class ChineseText extends Configurable implements TextProducer { public String getText() { int length = getConfig().getTextProducerCharLength(); //char[] charS = getConfig().getTextProducerCharString(); String[] s = new String[]{"我","愛(ài)","扎","瓦","和","賣(mài)","塞","扣"}; Random rand = new Random(); StringBuffer sb = new StringBuffer(); for(int i = ; i < length; i++){ int ind = rand.nextInt(s.length); sb.append(s[ind]); } return sb.toString(); } /** * 中午實(shí)例 * @return */ public String getText() { int length = getConfig().getTextProducerCharLength(); String finalWord = "", firstWord = ""; int tempInt = ; String[] array = { "", "", "", "", "", "", "", "", "", "", "a", "b", "c", "d", "e", "f" }; Random rand = new Random(); for (int i = ; i < length; i++) { switch (rand.nextInt(array.length)) { case : tempInt = rand.nextInt() + ; firstWord = String.valueOf((char) tempInt); break; case : int r, r, r, r; String strH, strL;// high&low r = rand.nextInt() + ; // 前閉后開(kāi)[,) if (r == ) { r = rand.nextInt(); } else { r = rand.nextInt(); } r = rand.nextInt() + ; if (r == ) { r = rand.nextInt() + ; } else if (r == ) { r = rand.nextInt(); } else { r = rand.nextInt(); } strH = array[r] + array[r]; strL = array[r] + array[r]; byte[] bytes = new byte[]; bytes[] = (byte) (Integer.parseInt(strH, )); bytes[] = (byte) (Integer.parseInt(strL, )); firstWord = new String(bytes); break; default: tempInt = rand.nextInt() + ; firstWord = String.valueOf((char) tempInt); break; } finalWord += firstWord; } return finalWord; } }
最后一步就是去web.xml中改文本實(shí)現(xiàn)類(lèi)的值,使組件調(diào)用自己寫(xiě)的那個(gè)類(lèi)產(chǎn)生中文驗(yàn)證碼。
<init-param> <description>文本實(shí)現(xiàn)類(lèi)</description> <param-name>kaptcha.textproducer.impl</param-name> <param-value> ChineseText </param-value> </init-param>
實(shí)現(xiàn)圖例:
算數(shù)運(yùn)算驗(yàn)證碼的實(shí)現(xiàn):
和上述中文驗(yàn)證碼相同,我們需要通過(guò)繼承類(lèi)和接口來(lái)實(shí)現(xiàn)自己的類(lèi),并改寫(xiě)其中的函數(shù),然后通過(guò)改配置信息來(lái)使組件調(diào)用自己實(shí)現(xiàn)的類(lèi)從而實(shí)現(xiàn)驗(yàn)證碼形式的多樣化。
KaptchaServlet字節(jié)碼文件經(jīng)過(guò)反編譯后的代碼如下:
public class KaptchaServlet extends HttpServlet implements Servlet { private Properties props = new Properties(); private Producer kaptchaProducer = null; private String sessionKeyValue = null; public void init(ServletConfig conf) throws ServletException { super.init(conf); ImageIO.setUseCache(false); Enumeration<?> initParams = conf.getInitParameterNames(); while (initParams.hasMoreElements()) { String key = (String)initParams.nextElement(); String value = conf.getInitParameter(key); this.props.put(key, value); } Config config = new Config(this.props); this.kaptchaProducer = config.getProducerImpl(); this.sessionKeyValue = config.getSessionKey(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setDateHeader("Expires", L); resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); resp.addHeader("Cache-Control", "post-check=, pre-check="); resp.setHeader("Pragma", "no-cache"); resp.setContentType("image/jpeg"); String capText = this.kaptchaProducer.createText(); req.getSession().setAttribute(this.sessionKeyValue, capText); BufferedImage bi = this.kaptchaProducer.createImage(capText); ServletOutputStream out = resp.getOutputStream(); ImageIO.write(bi, "jpg", out); try { out.flush(); } finally { out.close(); } } }
然后自己實(shí)現(xiàn)的KaptchaServlet.java代碼如下:在原來(lái)的字節(jié)碼文件上增加了實(shí)現(xiàn)加法驗(yàn)證碼的邏輯,通過(guò)比對(duì)即可發(fā)現(xiàn)。
public class KaptchaServlet extends HttpServlet implements Servlet { private Properties props; private Producer kaptchaProducer; private String sessionKeyValue; public KaptchaServlet() { this.props = new Properties(); this.kaptchaProducer = null; this.sessionKeyValue = null; } public void init(ServletConfig conf) throws ServletException { super.init(conf); ImageIO.setUseCache(false); Enumeration initParams = conf.getInitParameterNames(); while (initParams.hasMoreElements()) { String key = (String) initParams.nextElement(); String value = conf.getInitParameter(key); this.props.put(key, value); } Config config = new Config(this.props); this.kaptchaProducer = config.getProducerImpl(); this.sessionKeyValue = config.getSessionKey(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setDateHeader("Expires", L); resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); resp.addHeader("Cache-Control", "post-check=, pre-check="); resp.setHeader("Pragma", "no-cache"); resp.setContentType("image/jpeg"); String capText = this.kaptchaProducer.createText(); String s = capText.substring(, ); String s = capText.substring(, ); int r = Integer.valueOf(s).intValue() + Integer.valueOf(s).intValue(); req.getSession().setAttribute(this.sessionKeyValue, String.valueOf(r)); BufferedImage bi = this.kaptchaProducer.createImage(s+"+"+s+"=?"); ServletOutputStream out = resp.getOutputStream(); ImageIO.write(bi, "jpg", out); try { out.flush(); } finally { out.close(); } } }
我們還需在web.xml開(kāi)頭進(jìn)行更改配置使組件來(lái)調(diào)用自己實(shí)現(xiàn)的servlet:
<servlet-name>Kaptcha</servlet-name> <servlet-class> KaptchaServlet </servlet-class>
實(shí)現(xiàn)圖例:
總結(jié):
這里只是簡(jiǎn)單實(shí)現(xiàn)了驗(yàn)證碼,但要用到商業(yè)項(xiàng)目上還是遠(yuǎn)遠(yuǎn)不夠的,驗(yàn)證碼想要不被破解還要加上各種加密算法,即使這樣,也可以隨處搜索到某某驗(yàn)證碼被破解的情況。在網(wǎng)絡(luò)上有一個(gè)地下數(shù)據(jù)庫(kù),里面存儲(chǔ)的是我們的個(gè)人信息,那些信息都是一條條整理好的,這十分可怕,但這樣一個(gè)數(shù)據(jù)庫(kù)是客觀存在的,驗(yàn)證碼作為保護(hù)賬戶密碼的重要一環(huán),已變得越來(lái)越不安全,因?yàn)閭€(gè)人信息的泄露,別人掌握了你足夠的信息就可以對(duì)你實(shí)行詐騙,其中驗(yàn)證碼是重要一環(huán),近日就有一畢業(yè)生被騙取驗(yàn)證碼后,幾個(gè)小時(shí)內(nèi)所有財(cái)富都被轉(zhuǎn)走的事件發(fā)生。所以請(qǐng)保護(hù)好你的驗(yàn)證碼,不要輕易泄露給他人。
當(dāng)然我們也不會(huì)坐以待斃,目前的驗(yàn)證碼種類(lèi)繁多也越來(lái)越難以破解,像語(yǔ)音識(shí)別、面部識(shí)別這些都是耳熟能詳?shù)木筒欢嗾f(shuō)了。
這里我們引入一個(gè)驗(yàn)證碼“新”概念:雙因素認(rèn)證。
雙因素認(rèn)證是一種采用時(shí)間同步技術(shù)的系統(tǒng),采用了基于時(shí)間、事件和密鑰三變量而產(chǎn)生的一次性密碼來(lái)代替?zhèn)鹘y(tǒng)的靜態(tài)密碼。每個(gè)動(dòng)態(tài)密碼卡都有一個(gè)唯一的密鑰,該密鑰同時(shí)存放在服務(wù)器端,每次認(rèn)證時(shí)動(dòng)態(tài)密碼卡與服務(wù)器分別根據(jù)同樣的密鑰,同樣的隨機(jī)參數(shù)(時(shí)間、事件)和同樣的算法計(jì)算了認(rèn)證的動(dòng)態(tài)密碼,從而確保密碼的一致性,從而實(shí)現(xiàn)了用戶的認(rèn)證。因每次認(rèn)證時(shí)的隨機(jī)參數(shù)不同,所以每次產(chǎn)生的動(dòng)態(tài)密碼也不同。由于每次計(jì)算時(shí)參數(shù)的隨機(jī)性保證了每次密碼的不可預(yù)測(cè)性,從而在最基本的密碼認(rèn)證這一環(huán)節(jié)保證了系統(tǒng)的安全性。解決因口令欺詐而導(dǎo)致的重大損失,防止惡意入侵者或人為破壞,解決由口令泄密導(dǎo)致的入侵問(wèn)題。
簡(jiǎn)單來(lái)說(shuō),雙因素身份認(rèn)證就是通過(guò)你所知道再加上你所能擁有的這二個(gè)要素組合到一起才能發(fā)揮作用的身份認(rèn)證系統(tǒng)。例如,在ATM上取款的銀行卡就是一個(gè)雙因素認(rèn)證機(jī)制的例子,需要知道取款密碼和銀行卡這二個(gè)要素結(jié)合才能使用。目前主流的雙因素認(rèn)證系統(tǒng)是基于時(shí)間同步型,市場(chǎng)占有率高的有DKEY雙因素認(rèn)證系統(tǒng)、RSA雙因素認(rèn)證系統(tǒng)等,由于DKEY增加對(duì)短信密碼認(rèn)證及短信+令牌混合認(rèn)證支持,相比RSA,DKEY雙因素認(rèn)證系統(tǒng)更具競(jìng)爭(zhēng)力。
以上所述是小編給大家介紹的Java驗(yàn)證碼制作的相關(guān)內(nèi)容,希望對(duì)大家有所幫助!
- Java Web開(kāi)發(fā)過(guò)程中登陸模塊的驗(yàn)證碼的實(shí)現(xiàn)方式總結(jié)
- 探討Java驗(yàn)證碼制作(上篇)
- Javaweb開(kāi)發(fā)中通過(guò)Servlet生成驗(yàn)證碼圖片
- 基于JAVA的短信驗(yàn)證碼api調(diào)用代碼實(shí)例
- java驗(yàn)證碼生成具體代碼
- java生成圖片驗(yàn)證碼實(shí)例代碼
- Java版仿QQ驗(yàn)證碼風(fēng)格圖片驗(yàn)證碼
- java實(shí)用驗(yàn)證碼的實(shí)現(xiàn)代碼
- java下使用kaptcha生成驗(yàn)證碼
- Java Web項(xiàng)目中驗(yàn)證碼功能的制作攻略
相關(guān)文章
Java21增強(qiáng)對(duì)Emoji表情符號(hào)處理示例詳解
這篇文章主要為大家介紹了Java21增強(qiáng)對(duì)Emoji表情符號(hào)處理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11idea中javaweb的jsp頁(yè)面圖片加載不出來(lái)問(wèn)題及解決
這篇文章主要介紹了idea中javaweb的jsp頁(yè)面圖片加載不出來(lái)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07spring mvc 和ajax異步交互完整實(shí)例代碼
本篇文章主要介紹了spring mvc 和ajax異步交互完整實(shí)例代碼,簡(jiǎn)單的AJAX+SpringMVC的異步交互小例子,有興趣的可以了解一下。2017-02-02Java整合mybatis實(shí)現(xiàn)過(guò)濾數(shù)據(jù)
這篇文章主要介紹了Java整合mybatis實(shí)現(xiàn)過(guò)濾數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01自己動(dòng)手編寫(xiě)一個(gè)Mybatis插件之Mybatis脫敏插件
這篇文章主要介紹了自己動(dòng)手編寫(xiě)一個(gè)Mybatis插件之Mybatis脫敏插件,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08Java實(shí)現(xiàn)分頁(yè)的幾種方法詳細(xì)解析
這篇文章主要介紹了Java實(shí)現(xiàn)分頁(yè)的幾種方法詳細(xì)解析,在Java中想實(shí)現(xiàn)分頁(yè)功能有幾種常用的方法,今天我們就來(lái)詳細(xì)解析一下,文中提供了解決思路和部分實(shí)現(xiàn)代碼,需要的朋友可以參考下2023-11-11java 基礎(chǔ)之JavaBean屬性命名規(guī)范問(wèn)題
這篇文章主要介紹了java 基礎(chǔ)之JavaBean屬性命名規(guī)范問(wèn)題的相關(guān)資料,需要的朋友可以參考下2017-05-05