版本:Springboot3.2.3 maven3.6.3 JDK17
问题:2024-02-01T13:03:01.574+08:00 ERROR 8276 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalStateException: No primary or single unique constructor found for interface javax.servlet.http.HttpServletRequest] with root cause
这个问题的意思就是javax.servlet.http.HttpServletRequest这个接口找不到。
因为我所用的版本和我学习的版本不一致,学习的是springboot2.X版本,而我用的是3.X。Spring Boot 3.0废弃了JavaEE,改用了Jakarta EE,所以我们需要进行相应的修改:
首先,在pom.xml中加入依赖:
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
加入依赖后,将javax.*全部改成jakarta.*即可。
下面给出接口开发的代码,改成jakarta.*。
package net.xdclass.xdclassredis.controller;
import com.google.code.kaptcha.Producer;
import jakarta.annotation.Resource;
import net.xdclass.xdclassredis.util.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/api/v1/captcha")
public class CaptchaController {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private Producer captchaProducer;
@GetMapping("/get_captcha")
public void getCaptcha(HttpServletRequest request, HttpServletResponse response){
String captchaText = captchaProducer.createText();
String key = getCaptchaKey(request);
//10分钟过期
redisTemplate.opsForValue().set(key,captchaText,10,TimeUnit.MINUTES);
BufferedImage bufferedImage = captchaProducer.createImage(captchaText);
ServletOutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
ImageIO.write(bufferedImage,"jpg",outputStream);
outputStream.flush();
outputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}
private String getCaptchaKey(HttpServletRequest request){
String ip = CommonUtil.getIpAddr(request);
String userAgent = request.getHeader("User-Agent");
String key = "user-service:captcha:"+CommonUtil.MD5(ip+userAgent);
return key;
}
}
OK!现在直接去测试还会出现问题,因为在工具类里面也要进行修改,这里我就不放代码了。然后就是测试我们验证码是否可以生成并存储在Redis。
不知道什么原因,就显示8080端口被占用,这里我们使用cmd命令查看端口号占用情况。
netstat -ano | findstr 端口号
可以看到PID:2612进程已经存在,我们将这个进程结束即可,可以在设别管理器找到该进程然后结束掉,或者使用命令:
taskkill -PID 进程号 -F
OK。这样就不会显示8080端口被占用了。
接下来,我们debug下,然后断点调试,再浏览器输入localhost:8080/api/v1/captcha/get_captcha
显示验证码:
然后看一下debug结果:
显然,通过MD5进行了加密。最后看一下Redis数据库里是否有相应验证码。
结果一致,搞定!