更改数据库的密码 以及我的redis当时是没有设置密码的 也要进行改动
注意点:
我是直接在D盘删除mysql文件夹,应该是清理不到位的。
因此,在安装mysql的时候,要注意几个方面:
针对拒绝访问这个问题:一定要在管理员身份下打开cmd.
针对系统找不到指定的文件这个问题:除了要检查高级设置里的配置环境外,要将下载的mysql下载回原来mysql的位置。eg:我原来的mysql下载在D盘,那我重新安装mysql的时候就要放在D盘。
其余的跟着黑马的JAVAWEB2023下载mysql即可以。
bug3 重新安装mysql后,在导入sql文件的时候,出现了database selected问题。
解决方案:
1、检查database的密码和用户是否正确
2、记住database的名称,这里叫作hmdp。所以创建的时候也要是hmdp
然后在相对应的控制台将sql文件复制黏贴执行就可以啦。
实战篇3
实战篇5
细节:反向编码,避免层层嵌套的编码方式,使代码更加清晰。
@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {
//1,校验手机号
String phone = loginForm.getPhone();
if (RegexUtils.isPhoneInvalid(phone)) {
//2.如果不符合,返回错误信息
return Result.fail("手机格式错误!");
}
//2,校验验证码
Object cacheCode = session.getAttribute("code");
String code = loginForm.getCode();
if (cacheCode == null || !cacheCode.toString().equals(code)) {
//3,不一致,报错
return Result.fail("校验码错误");
}
//4,一致,根据手机号查询用户
User user = query().eq("phone", phone).one();
//5,判断用户是否存在
if (user == null) {
//6,不存在,创建新用户并保存
user = createUserWithPhone(phone);
}
//7,保存用户信息到session
session.setAttribute("user", user);
return Result.ok();
}
private User createUserWithPhone(String phone){
User user = new User();
user.setPhone(phone);
user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
save(user);
return null;
}
实战篇6
一次性拦截,不用每次访问controller都要拦截一次
package com.hmdp.utils;
import com.hmdp.dto.UserDTO;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1,获取session
HttpSession session =request.getSession();
//2,获取session中的用户
Object user = session.getAttribute("user");
//3,判断用户是否存在
if(user == null){
//4,不存在,拦截,返回401状态码
response.setStatus(401);
return false;
}
//5,存在,保存用户信息到ThreadLocal
UserHolder.saveUser((UserDTO) user);
//6,放行
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//移除用户
UserHolder.removeUser();
}
}
package com.hmdp.config;
import com.hmdp.utils.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns(
"/shop/**",
"/voucher/**",
"/shop-type/**",
"/upload/**",
"/blog/hot",
"/user/code",
"/user/login"
);
}
}
细节:
1,alt +insert 可以快捷生成方法
2,长按ctrl 选择两个以上的东西
3,@Configuration用于定义配置类
实战篇7
因为返回完整的用户信息,容易产生敏感信息泄露的问题,因此得解决它。
再做一个UserDTO来封装信息。
//7,保存用户信息到session
session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));
return Result.ok();
细节:
1,User是个类名,User.class会得到一个Class(字节码对象)类型的对象,这个对象包含这个类的所有属性
实战篇8
实战篇9
以手机号码为key获取验证码
以token为key用于访问页面,用token而不用手机号码可以减少隐私泄露的风险。
后端要将token返回给前端
采用Hash结构,有利于修改信息,也可以减少存储的内容(比如存储的格式)
实战篇10
@resource
因此,现在是会报错的。
所以解决方案有:
1、删除一个myservice
2、写清楚到底是注入哪一个名称。比如它这里写清楚是注入没有serviceimpl01
@autowired
解决方案:
2,加上@Qualifier
3,删除service,只保留一个service
来源视频面试:@Resource和@Autowired区别?_哔哩哔哩_bilibili
细节:
1,设置过期时间:expire
eg:stringRedisTemplate.expire("baike",1000 , TimeUnit.MILLISECONDS);
2,当项目中有许多JAVA类,想快速找到想要的JAVA类,则按Ctrl + E 可以出现选择框选择。
public class LoginInterceptor implements HandlerInterceptor {
private StringRedisTemplate stringRedisTemplate;
public LoginInterceptor(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1,获取请求头中的token
String token = request.getHeader("authorization");
if(StrUtil.isBlank(token)) {
response.setStatus(401);
return false;
}
//2,基于token获取redis中的用户
String key = RedisConstants.LOGIN_USER_KEY + token;
Map
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl implements IUserService {
//注入redis的配置
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public Result sendcode(String phone, HttpSession session) {
//1.校验手机号
if(RegexUtils.isPhoneInvalid(phone)){
//2.如果不符合,返回错误信息
return Result.fail("手机格式错误!");
}
//3.符合,生成验证码
String code = RandomUtil.randomNumbers(6);
//4.保存验证码到redis
stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY+phone,code,LOGIN_CODE_TTL, TimeUnit.MINUTES);
//5.发送验证码
log.info("发送短信验证码成功,验证码:{}",code);
//返回ok
return Result.ok();
}
@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {
//1,校验手机号
String phone = loginForm.getPhone();
if (RegexUtils.isPhoneInvalid(phone)) {
//2.如果不符合,返回错误信息
return Result.fail("手机格式错误!");
}
//3,从redis获取验证码并校验
String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
String code = loginForm.getCode();
if (cacheCode == null || !cacheCode.toString().equals(code)) {
//不一致,报错
return Result.fail("校验码错误");
}
//4,一致,根据手机号查询用户
User user = query().eq("phone", phone).one();
//5,判断用户是否存在
if (user == null) {
//6,不存在,创建新用户并保存
user = createUserWithPhone(phone);
}
//7,保存用户信息到redis
//7.1 随机生成token,作为登陆令牌
String token = UUID.randomUUID().toString();
//7.2 将User对象转为HashMap存储
UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
Map userMap = BeanUtil.beanToMap(userDTO,new HashMap<>(),
CopyOptions.create()
.setIgnoreNullValue(true)
.setFieldValueEditor((fieldName,fieldvalue)->fieldvalue.toString()));
//7.3存储
String tokenKey = LOGIN_USER_KEY + token;
stringRedisTemplate.opsForHash().putAll(tokenKey,userMap);
//7.4 设置token有效期
stringRedisTemplate.expire(tokenKey,LOGIN_USER_TTL,TimeUnit.MINUTES);
//8 返回token
return Result.ok();
}
private User createUserWithPhone(String phone){
User user = new User();
user.setPhone(phone);
user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
save(user);
return null;
}
}
一些小问题:如果只有原先的一个拦截器的话,它只会拦截需要登录的路径,对于不需要登录的路径它不拦截。这就会导致如果用户没有登陆就访问页面的话,那三十分钟后token不会自动刷新,那就会造成token失效,不合理。
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1,判断是否需要拦截(ThreadLocal中是否有用户)
if (UserHolder.getUser() == null) {
// 没有,需要拦截,设置状态码
response.setStatus(401);
//拦截
return false;
}
//由用户,则放行
return true;
}
}
public class RefreshTokenInterceptor implements HandlerInterceptor {
private StringRedisTemplate stringRedisTemplate;
public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1,获取请求头中的token
String token = request.getHeader("authorization");
if(StrUtil.isBlank(token)) {
return true;
}
//2,基于token获取redis中的用户
String key = LOGIN_USER_KEY + token;
Map
注意点:
1,