${pageContext.request.contextPath}访问不到,验证码刷新失败

  • 背景:
  • 问题1(${pageContext.request.contextPath}访问不到)原因:
  • 解决方案:
  • 后续
  • 问题2(验证码刷新失败)原因:
  • 解决方案:
  • 生成验证码的servlet:

背景:

原本想写一个验证码图片,但是写好之后,在前端就是拿不到图片,路径也没啥错误。项目结构如下:

Mapping配置如下:

  <servlet><servlet-name>verificationImage</servlet-name><servlet-class>com.ljh.servlet.VerificationImage</servlet-class></servlet><servlet-mapping><servlet-name>verificationImage</servlet-name><url-pattern>/vg</url-pattern></servlet-mapping>

前端代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*"%>
<html>
<body>
<form action="${pageContext.request.contextPath}/loginCheck" method="post">验证码:<input type="text" name="validateCode"/><img alt="换一张" src="${pageContext.request.contextPath}/vg" id="validateCodeImg" onclick="changeImg()"><a href="javascript:void(0)" onclick="changeImg()">看不清楚换一张</a><br/><input type="submit" value="提交">
</form>
</body>
<script type="text/javascript">//刷新验证码function changeImg(){document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/vg";}
</script>
</html>

诶,结果他就这样,

刚开始,以为路径有问题,就直接访问一把生成验证码图片的 servlet,诶,它成功访问。不是路径问题、、、、、、、

接下来我就好奇,为啥呢?我就把前端加个链接,然后直接点一手看他跳到哪?

<a href="${pageContext.request.contextPath}/vg">给我跳!</a>

好好的地址成乱码了,懂了,就是没解析到写的地址呗?为啥没解析呢?拿着错误查了一下,知道问题在哪了。

问题1(${pageContext.request.contextPath}访问不到)原因:

${} 没有解析出来。
<%@ page isELIgnored="true|false"%>如果设定为真,那么JSP中的表达式被当成字符串处理,
我们通过字面意思理解一下:是否忽略el表达式,如果为true就是忽略el表达式,就是当做字符串来处理;
反之,就是按el表达式来。

解决方案:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>

后续

本以为就好了,谁知道还有问题,就是狂点看不清,换一张,但是这图片就是不换,咋回事呢:
尝试点刷新,诶,能换,那就是script那段写的有问题。左思右想。难道是点完没执行changeImg()函数吗?尝试修改然后加上两句话,看看到底有没有执行。

function changeImg(){alert("我执行了");document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/vg";alert("我也执行了");}



都执行了。。。。
再思考一下:

1. 拿到validateCodeImg控件
2. 把"${pageContext.request.contextPath}/vg"赋值给该控件的validateCodeImg
3. 没啥问题呀,啊不对,仔细一想,原本上面的在表单里的src初始值是"${pageContext.request.contextPath}/vg",那么这一步调用了"changeImg()"函数后,把值改成"${pageContext.request.contextPath}/vg",就简单认为src重新访问了一遍servlet,得到个新的图像,但是实际不是这样,而且这样根本没有刷新src,因为当第一次请求到"${pageContext.request.contextPath}/vg"之后,这个值一直都在,所以就算又调用一遍"changeImg()",相当于把这个值又给src赋值了一遍,没什么意义的操作。
4. 那么想解决,就需要保证当调用"changeImg()"时候,会重新访问一边"${pageContext.request.contextPath}/vg",怎么做呢? document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/vg?"+Math.random();

问题2(验证码刷新失败)原因:

重新点更换图片的时候,validateCodeImg控件的src并不会重新去后端请求一遍${pageContext.request.contextPath}/vg,而是将上次请求到
${pageContext.request.contextPath}/vg的值,重新又给了src,那么验证码图片将不会刷新。

document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/vg"

解决方案:

<script type="text/javascript">function changeImg(){document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/vg?"+Math.random();}
</script>

终于好了,nice。

生成验证码的servlet:

没加线条和噪声点 (o。o)

//VerificationImage.javaimport javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;public class VerificationImage extends HttpServlet {private final int WIDTH =  160;private final int HEIGHT = 40;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8");
//        resp.setHeader("refresh","5");Random random = new Random();//在内存中生成一个画布BufferedImage bufferedImage = new BufferedImage(WIDTH,HEIGHT,1);//可以理解为 拿到画笔Graphics graphics = bufferedImage.getGraphics();//设置画笔颜色graphics.setColor(new Color(197,197,197));//用画笔的颜色涂满 规定区域,这里主要是画出背景色graphics.fillRect(0,0,WIDTH,HEIGHT);//将画笔转为2dGraphics2D g2 = (Graphics2D)graphics;//设置画笔的字体g2.setFont(new Font("宋体",Font.BOLD, 34));//生成随机4位数字int rdmInt = random.nextInt(9999-1000+1)+1000;//将数字存到sessionreq.getSession().setAttribute("vgCode",rdmInt+"");int num, x = 3;while (rdmInt > 0){//随机生成一个颜色,用来画出其中一个数字//原本random.nextInt(127)可以是RGB的0-255,但这里设置127是怕到时候生成的画笔颜色太靠近255,太亮//可能会跟底色一样的颜色,就看不出来了,所以让他颜色暗一点g2.setColor(new Color(random.nextInt(127),random.nextInt(127),random.nextInt(127)));//除10模10拿到其中一个数字num = rdmInt % 10;rdmInt = rdmInt / 10;//随机生成一个倾斜角int degree = random.nextInt() % 30;//设置画笔偏向角度g2.rotate(degree * Math.PI / 180, x, 34);//用画笔画出其中一个数字g2.drawString(num+"", x, 34);//将画笔调正,防止下次生成角度之前,画笔已经是歪的g2.rotate(-degree * Math.PI / 180, x, 34);x += 40;}g2.dispose();//设置响应头控制浏览器不缓存resp.setDateHeader("expries", -1);resp.setHeader("Cache-Control","no-cache");resp.setHeader("Pragma","no-cache");//将图片写给浏览器ImageIO.write(bufferedImage,"JPEG",resp.getOutputStream());}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

最新文章

  1. wxWidgets:wxStringBuffer类用法
  2. 【miscellaneous】IP多播技术及其编程
  3. 用辩证、动态的眼光看世界
  4. 如何腾出计算机内存,win7系统(取消)删除虚拟内存让硬盘空间轻松腾出来
  5. 把Python程序的输出和异常信息自动写入文件
  6. springboot执行批量插入_springboot+Mybatis 注解\Xml两种方式批量添加数据
  7. WebLogic 12c 中压缩传输的配置
  8. zabbix配置微信报警
  9. 金九银十招聘季,程序员跳槽BAT最新面经
  10. python学习笔记4-切片
  11. 澳门大学计算机qs排名,澳门大学世界QS排名
  12. 通俗地讲一下庞加莱猜想是怎么回事(from 鼓浪)
  13. 罗永浩、戴威的C位消亡史
  14. 现在企业常用考勤软件
  15. 【K8S】整体原理-K8S网络
  16. JVM之记忆集和卡表
  17. 【日常】矩阵正态分布参数检验问题
  18. R语言 devtools
  19. linux module load, show, 包管理,找到包的路径
  20. 办公自动化系统OA市场发展新趋势

热门文章

  1. Windows XP SP2 TCP/IP连接数的查看与修改
  2. 基础爬虫系列课程授课内容3——xpath语法
  3. sift特征提取python
  4. URLWithString返回nil问题
  5. 学习笔记 4 — 图像拼接【Image Panoramic Mosaic】
  6. android打造独一无二的loading动画效果
  7. 40万年才能遇到外星人,是怎么算出来的?
  8. c#中的Nullable(可空类型)
  9. 百兆/千兆车载以太网转换器 泰科MQS接口
  10. QuantLib 金融计算——收益率曲线之构建曲线(3)