java踩坑日记
Posted flowernotgiveyou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java踩坑日记相关的知识,希望对你有一定的参考价值。
1:环境:idea 14版本,win10,springboot
2:第一个问题:必须使用shiro实现登录(加验证码)
参考资料: https://blog.csdn.net/qq_34021712/article/details/80470738 ©王赛超
验证码校验:
@RequestMapping(value = "/login",method = RequestMethod.POST) public String loginUser(HttpServletRequest request, String username, String password,boolean rememberMe,String captcha, Model model) //校验验证码 //session中的验证码 String sessionCaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(CaptchaController.KEY_CAPTCHA); if (null == captcha || !captcha.equalsIgnoreCase(sessionCaptcha)) model.addAttribute("msg","验证码错误!"); return "login"; //对密码进行加密 //password=new SimpleHash("md5", password, ByteSource.Util.bytes(username.toLowerCase() + "shiro"),2).toHex(); //如果有点击 记住我 UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password,rememberMe); //UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password); Subject subject = SecurityUtils.getSubject(); try //登录操作 subject.login(usernamePasswordToken); return "redirect:index"; catch(Exception e) //登录失败从request中获取shiro处理的异常信息 shiroLoginFailure:就是shiro异常类的全类名 String exception = (String) request.getAttribute("shiroLoginFailure"); if(e instanceof UnknownAccountException) model.addAttribute("msg","用户名或密码错误!"); if(e instanceof IncorrectCredentialsException) model.addAttribute("msg","用户名或密码错误!"); if(e instanceof LockedAccountException) model.addAttribute("msg","账号已被锁定,请联系管理员!"); //返回登录页面 return "login";
此处我将此模块放在logincontroller里面专门处理登录操作;下面的为验证码的生成;新建一个CaptchaUtil将它放在utils下面,标黄的地方注意是你自己定义的路径
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
/**
* 验证码工具类
*/
public class CaptchaUtil
// 随机产生的字符串
private static final String RANDOM_STRS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String FONT_NAME = "Fixedsys";
private static final int FONT_SIZE = 18;
private Random random = new Random();
private int width = 80;// 图片宽
private int height = 25;// 图片高
private int lineNum = 50;// 干扰线数量
private int strNum = 4;// 随机产生字符数量
/**
* 生成随机图片
*/
public BufferedImage genRandomCodeImage(StringBuffer randomCode)
// BufferedImage类是具有缓冲区的Image类
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_BGR);
// 获取Graphics对象,便于对图像进行各种绘制操作
Graphics g = image.getGraphics();
// 设置背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
// 设置干扰线的颜色
g.setColor(getRandColor(110, 120));
// 绘制干扰线
for (int i = 0; i <= lineNum; i++)
drowLine(g);
// 绘制随机字符
g.setFont(new Font(FONT_NAME, Font.ROMAN_BASELINE, FONT_SIZE));
for (int i = 1; i <= strNum; i++)
randomCode.append(drowString(g, i));
g.dispose();
return image;
/**
* 给定范围获得随机颜色
*/
private Color getRandColor(int fc, int bc)
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
/**
* 绘制字符串
*/
private String drowString(Graphics g, int i)
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
.nextInt(121)));
String rand = String.valueOf(getRandomString(random.nextInt(RANDOM_STRS
.length())));
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(rand, 13 * i, 16);
return rand;
/**
* 绘制干扰线
*/
private void drowLine(Graphics g)
int x = random.nextInt(width);
int y = random.nextInt(height);
int x0 = random.nextInt(16);
int y0 = random.nextInt(16);
g.drawLine(x, y, x + x0, y + y0);
/**
* 获取随机的字符
*/
private String getRandomString(int num)
return String.valueOf(RANDOM_STRS.charAt(num));
public static void main(String[] args)
CaptchaUtil tool = new CaptchaUtil();
StringBuffer code = new StringBuffer();
BufferedImage image = tool.genRandomCodeImage(code);
System.out.println("random code = " + code);
try
// 将内存中的图片通过流动形式输出到客户端
ImageIO.write(image, "JPEG", new FileOutputStream(new File(
"/Users/wangsaichao/Desktop/random-code.jpg")));
catch (Exception e)
e.printStackTrace();
登录界面的代码,如果是这样的话你会发现页面根本不会出现验证码,标黄部分是验证码刷新代码,你必须调用此方法来进行验证码的生成,标红部分为你的logincontroller里面的方法路径。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <head> <meta charset="UTF-8" /> <title>Insert title here</title> </head> <body> <h1>欢迎登录</h1> <h1 th:if="$msg != null " th:text="$msg" style="color: red"></h1> <form action="/login" method="post"> 用户名:<input type="text" name="username"/><br/> 密码:<input type="password" name="password"/><br/> 验证码:<input type="text" name="captcha"/><img alt="验证码" th:src="@/Captcha.jpg" title="点击更换" id="captcha_img"/> (看不清<a href="javascript:void(0)" onclick="javascript:refreshCaptcha()">换一张</a>)<br/> <input type="checkbox" name="rememberMe" />记住我<br/> <input type="submit" value="提交"/> <button><a href="/unlockAccount">解锁admin用户</a></button> </form> </body> <script type="text/javascript"> window.οnlοad=kickout();
加上:
$(function()
refreshCaptcha();
)
function refreshCaptcha()
$("#captcha_img").attr("src","/Captcha.jpg?id=" + new Date() + Math.floor(Math.random()*24));
</script>
</html>
然后说说我遇到的问题:账号密码输入正确但是登陆不了,原因就是shiro默认会将你的密码进行md5加密,匹配的时候要么将shiro的md5加密去掉,要么就是将密码进行md5加密后再进行匹配。shiro是不需要你进行数据库查找的,他默认的进行了这一操作。
3.第二个问题,普遍的跳转
方式有多种,这里只说的是controller里面的跳转:
@RequestMapping("/") public String index() return "login"; @RequestMapping("/") public String index() return "redirect:/login";
上述的两种跳转是比较多的,第一种,直接return,那么它是找的你的.jsp文件。第二种,redirect:/login解释为重定向,他会在controller里面找到相应的以RequestMapping("/login")为开头的方法。然后进行跳转。
另外的涉及到页面的相互传值的问题(跳转),以一个案例来分析
logincontroller里面
@RequestMapping("/edit") public String userEdit(Model model, HttpServletRequest request) String id = request.getParameter("id"); int userid = Integer.parseInt(id); 方法 model.addAttribute("user", uservo);传值方式 return "页面"; @RequestMapping("/editUser") @ResponseBody public ResultVo edit(UserEntity userEntity) ResultVo result = new ResultVo(); 方法 if (CommonUtil.isNotNull(userVo)) result.setSuccess(false); else result.setSuccess(true); return result; 页面主要的ajax传值代码 $.ajax( type: "POST", async: "false", dataType1: "json", data : t, url: "$root/user/editUser", //传入值 success: function (data) if(data.success) window.location.href =‘$root/edit‘; //跳转界面 );
流程为:主页面加载完成:点击编辑按钮,在editUser里面进行判断,返回的result为true和false,如果返回为true则会跳转到edit,edit跳转到相应的页面。
以上是关于java踩坑日记的主要内容,如果未能解决你的问题,请参考以下文章
Vue 踩坑日记二:View UI 组件添加单击事件不生效问题
Android 踩坑日记 - RecyclerView 布局问题
踩坑日记:java.lang.IllegalStateException: For queries with named parameters you need to use provide ...