为什么我javaweb前端验证码这块无法显示图片,就是这种验证码图片出现立即消失并显示替代文本,点击它也是立即出现然后替代文本,想问一下怎么解决,比较急。
这是我的util包中的制作验证码图片的代码
package com.example.myproject.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
public class VerifyCode {
private int w = 100;
private int h = 40;
private Random r = new Random();
// {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
private String[] fontNames =
{ "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" };
// 可选字符
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
// 背景色
private Color bgColor = new Color(255, 255, 255);
// 验证码上的文本
private String text;
// 生成随机的颜色
private Color randomColor() {
int red = r.nextInt(150);
int green = r.nextInt(150);
int blue = r.nextInt(150);
return new Color(red, green, blue);
}
// 生成随机的字体
private Font randomFont() {
int index = r.nextInt(fontNames.length);
String fontName = fontNames[index];// 生成随机的字体名称
int style = r.nextInt(4);// 生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
int size = r.nextInt(5) + 24; // 生成随机字号, 24 ~ 28
return new Font(fontName, style, size);
}
// 画干扰线
private void drawLine(BufferedImage image) {
int num = 3;// 一共画3条
Graphics2D g2 = (Graphics2D) image.getGraphics();
for (int i = 0; i < num; i++) {// 生成两个点的坐标,即4个值
int x1 = r.nextInt(w);
int y1 = r.nextInt(h);
int x2 = r.nextInt(w);
int y2 = r.nextInt(h);
g2.setStroke(new BasicStroke(1.5F));
g2.setColor(Color.BLUE); // 干扰线是蓝色
g2.drawLine(x1, y1, x2, y2);// 画线
}
}
// 随机生成一个字符
private char randomChar() {
int index = r.nextInt(codes.length());
return codes.charAt(index);
}
// 创建BufferedImage
private BufferedImage createImage() {
BufferedImage image = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) image.getGraphics();
g2.setColor(this.bgColor);
g2.fillRect(0, 0, w, h);
return image;
}
// !调用这个方法得到验证码
public BufferedImage getImage() {
BufferedImage image = createImage();// 创建图片缓冲区
Graphics2D g2 = (Graphics2D) image.getGraphics();// 得到绘制环境
StringBuilder sb = new StringBuilder();// 用来装载生成的验证码文本
// 向图片中画4个字符
for (int i = 0; i < 4; i++) {// 循环四次,每次生成一个字符
String s = randomChar() + "";// 随机生成一个字母
sb.append(s); // 把字母添加到sb中
float x = i * 1.0F * w / 4; // 设置当前字符的x轴坐标
g2.setFont(randomFont()); // 设置随机字体
g2.setColor(randomColor()); // 设置随机颜色
g2.drawString(s, x, h - 5); // 画图
}
this.text = sb.toString(); // 把生成的字符串赋给了this.text
drawLine(image); // 添加干扰线
return image;
}
// 返回验证码图片上的文本
public String getText() {
return text;
}
// 保存图片到指定的输出流
public static void output(BufferedImage image, OutputStream out)
throws IOException {
ImageIO.write(image, "JPEG", out);
}
}
这是我响应这块
package com.example.myproject.controller;
import com.example.myproject.service.Userservse;
import com.example.myproject.utils.VerifyCode;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
@RestController
@RequestMapping("/api")
public class CaptchaController {
private final VerifyCode verifyCode = new VerifyCode();
@Autowired
private Userservse userservse;
@GetMapping("/captcha")
public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
BufferedImage captchaImage = verifyCode.getImage();
response.setContentType("image/jpeg");
ImageIO.write(captchaImage, "jpeg", response.getOutputStream());
HttpSession session=request.getSession();
session.setAttribute("captcha", verifyCode.getText());
}
@RequestMapping("forgetit")
public String forgetit(String userPhone,String newpassword,String recognise, Model model, HttpSession session)
{
String sessionCaptcha = (String) session.getAttribute("captcha");
if(recognise.equals(sessionCaptcha))
{
model.addAttribute("error", "验证码错误");
return "index";
}
else
{
boolean userExists = userservse.forgott(userPhone);
if(userExists)
{
userservse.renew(newpassword,userPhone);
return "index";
}
else
{
model.addAttribute("error", "不存在此电话号码");
return "forgetPassword";
}
}
}
}
这是我的前端代码
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>忘记密码</title>
<link rel="stylesheet" type="text/css" href="../static/forget.css">
<link rel="stylesheet" type="text/css" href="../static/fontawesome-free-6.7.2-web">
</head>
<body>
<div class="head1">
<h1>
修养生息——为年轻人创造的养生服务平台
</h1>
</div>
<div class="containerr">
<div class="log_intext">
<h1>
忘记密码
</h1>
</div>
<div class="log_in">
<form th:action="@{/forgetit}" th:method="post">
<span>
<i class="fa-solid fa-phone"></i>
<input type="text" placeholder="请输入手机号码" name="userPhone">
</span>
<br>
<span>
<i class="fa-solid fa-user"></i>
<input type="text" placeholder="请输入新密码" name="newpassword">
</span>
<br>
<span class="input-with-captcha">
<input type="text" class="half-width" placeholder="请输入验证码" name="recognise">
<img src="/api/captcha" alt="验证码" class="captcha-image" onclick="this.src='/api/captcha?'+Math.random();">
</span>
<br>
<button>提交</button>
</form>
</div>
<div class="elsesetiong">
<label>
<a th:href="@{/tolog_in}" style="margin-right: 140px;">
返回登录
</a>
<a th:href="@{/toRegister}" >
注册账号
</a>
</label>
</div>
</div>
</body>
</html>
body{
width: 1200px;
margin: 0 auto;
background-image:url(/static/log_inbackground.png);
background-repeat: no-repeat;
background-size: cover;
overflow:hidden;
}
.head1 h1
{
display: flex;
background-color: transparent;
font-size: 40px;
font-family: "华文新魏";
color: forestgreen;
margin: 20px 0px 0px;
justify-content: center;
overflow: hidden;
}
.containerr
{
width: 300px;
margin: 7% auto;
border-radius: 25px;
background-color: rgba(0,0,0,0.1);
box-shadow: 0 0 17px #333;
}
.log_intext
{
text-align: center;
padding-top: 75px;
padding-bottom: 60px;
font-family: "华文新魏";
color: #006400;
}
.log_in
{
padding-left: 45px;
}
.log_in button,input
{
width: 200px;
height: 40px;
border: none;
outline: none;
padding-left: 40px;
box-sizing: border-box;
font-size: 15px;
color: #333;
margin-bottom: 20px;
}
.log_in button
{
padding-left: 0;
background-color: #83acf1;
letter-spacing: 1px;
font-weight: bold;
margin-bottom: 50px;
margin-top: 20px;
border-radius:10px;
}
.log_in button:hover
{
box-shadow: 2px 2px 5px #555;
background-color: #7799d4;
}
.log_in input:hover
{
box-shadow: 2px 2px 5px #555;
background-color: #ddd;
}
.log_in span
{
position:relative;
}
.log_in i
{
position: absolute;
left:15px;
color:#333;
font-size: 16px;
top:2px;
}
.elsesetiong
{
padding-bottom: 10px;
padding-left: 10px;
}
.elsesetiong a
{
text-decoration: none;
color: #555555;
}
.half-width
{
padding: 0;
width:100px;
text-align: left;
margin-left: 0;
margin-right: 0;
}
.input-with-captcha {
display: flex;
align-items: center; /* 垂直居中 */
}
.input-with-captcha input {
/* 这里可以保留.half-width类的样式,或者根据需要调整 */
/* 让输入框占据剩余空间 */
margin-right: 10px; /* 输入框和图片之间的间距 */
}
.captcha-image {
padding: 0;
width:100px;
text-align: left;
margin-left: 0;
margin-right: 0;
height: 40px;
overflow: hidden;/* 根据需要调整图片高度,与输入框高度相匹配 */
/* 根据图片原始比例调整宽度 */
}