在这个加长版寒假里,为了挤进学校的实验室里打下手
,我花了好长时间完成了这份大作业,至少对我这个假期才刚刚接触后端的新人来说这份大作业属实不简单。
不过也是顺利完成了,发出来给大伙们乐乐~~希望大家能给给建议啥的~
1.工具:
开发软件:IDEA //IDEA,永远滴神!!数据库:mysql
测试工具:火狐浏览器和postman
2.思路:
登录功能:用mysql数据库保存注册过的用户,每次登录后若通过验证,则返还给前端一个token,并将页面转到登录过后的收藏页面,之后前端每一次请求都要带上所给的token,后端使用拦截器进行校验,校验成功才能完成请求。
收藏功能:使用@Query注释进行原生的mysql语句(我觉得这样比较自由,且所提供的查询我也不太了解,可能是我太菜了吧~而且我也不会模糊查询啥的,只会头铁的进行对比查询)进行增删查改的操作,将整个程序大致分为Controller(控制层),Servise(服务层),Dao(Dao层),是代码清晰。
日志功能:我就学了皮毛,简单运用了SpringBoot的AOP切面原理,自定义一个注解,将注解放到想要监控的方法上,用Aspect层进行记录日志 。
3.上代码!
先康康代码结构:
确实是挺简单的先看Login部分
LoginController:
```java
package com.example.collet.controller;
import com.example.collet.annotation.MyLog;
import com.example.collet.interceptor.JwtAuthenticationFilter;
import com.example.collet.interceptor.JwtUtil;
import com.example.collet.service.ColletionService;
import com.example.collet.service.LoginService;
import com.example.collet.Entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class LoginController {
@Autowired
private LoginService ls;
@Autowired
private ColletionService cs;
@RequestMapping
public ModelAndView loginpage() {
return new ModelAndView("login.html");
}
//处理登录信息
@MyLog(value = "登录")
@RequestMapping(value = "/Login")
public ModelAndView finduser(@RequestParam("username") String username,
@RequestParam("userpassword") String password){
if(ls.finduser(username)!=null){
if(ls.findpassword(username,password)){
//登入成功
String token= JwtUtil.generateToken(username);
ModelAndView model=new ModelAndView("demo.html","massage","欢迎"+username);
model.addObject("FavoriteList",cs.findall());
model.addObject("maxplatform",cs.maxplatform());
model.addObject("maxclass",cs.maxclass());
model.addObject("token",token); //把token放到model里,一起返回给前端
return model;
}else {
return new ModelAndView("login.html","massage","密码错误");
}
}else {
return new ModelAndView("login.html","massage","查无此人");
}
}
//转到注册页面
@PostMapping(value = "/Signin")
public ModelAndView signinpage(){
return new ModelAndView("signin.html");
}
//处理注册信息
@MyLog(value = "注册")
@RequestMapping(value = "/ReduceSignin")
public ModelAndView sign(@RequestParam("username") String username,
@RequestParam("password") String password,
@RequestParam("repassword") String repassword){
User u=new User();
u.setusername(username);
u.setuserpassword(password);
//两次输入的密码是否匹配
if (password.equals(repassword)) {
//查看用户名是否存在
if (ls.finduser(username)==null){
ls.adduser(u);
return new ModelAndView("login.html","massage","注册成功");
}else{
return new ModelAndView("login.html","massage","用户已存在");
}
}else{
return new ModelAndView("signin.html","massage","两次输入的密码不匹配");
}
}
//注册拦截器
@Bean
public FilterRegistrationBean jwtFilter() {
final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
JwtAuthenticationFilter filter = new JwtAuthenticationFilter();
registrationBean.setFilter(filter);
return registrationBean;
}
}
LoginServse:
```java
```java
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class LoginService {
@Autowired
private LoginDao urp;
//查询所有可登录的名单
@Transactional
public User find() { return (User) urp.findAll(); }
//处理注册信息
@Transactional
public void adduser(User person) { urp.adduser(person.getusername(),person.getuserpassword()); }
//按照名字查询账号
@Transactional
public User finduser(String name){
return urp.findbyname(name);
}
//在确保账号在数据库中存在的情况下核对密码
@Transactional
public boolean findpassword(String username,String password) {
//判断是否存在username
if(urp.findbyname(username).getuserpassword().equals(password))
return true;
else
return false;
}
}
LoginDao:
```java
package com.example.collet.dao;
import com.example.collet.Entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface LoginDao extends JpaRepository<User,String>{
//相对于名字相等查询,参数为name
@Query(value = "select * from user where username=?1", nativeQuery = true)
User findbyname(String name);
//加入user
@Modifying
@Query(value = "insert into user(username,userpassword) values(?1,?2)",nativeQuery = true)
void adduser(String name,String password);
}
拦截器:
JwtAuthenticationFilter:
```java
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final PathMatcher pathMatcher = new AntPathMatcher();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
if(isProtectedUrl(request)) {
//String token = request.getHeader("token"); //检查http的头部,由于我不会将token放到头部,故不用
String token=request.getParameter("token");
//检查jwt令牌, 如果令牌不合法或者过期, 里面会直接抛出异常, 下面的catch部分会直接返回
JwtUtil.validateToken(token);
}
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
return;
}
//如果jwt令牌通过了检测, 那么就把request传递给后面
filterChain.doFilter(request, response);
}
//我们只对地址 /Collect 开头检查jwt. 不然的话登录/login也需要jwt
private boolean isProtectedUrl(HttpServletRequest request) {
return pathMatcher.match("/Collect/**", request.getServletPath());
}
}
JwtUtil:
package com.example.collet.interceptor;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;<