一、登录功能开发
1.首先导入项目需要的前端资源,放到resource下面。
2.配置启动类:TakeAwayApplication
1.@ServletComponentScan注解的作用是启用@WebServlet、@WebFilter和@WebListener注解的自动注册。在Spring Boot中,使用该注解可以让Spring Boot自动扫描@WebServlet、@WebFilter和@WebListener注解,并将它们注册到Servlet容器中。
2.在使用Spring Boot开发Web应用程序时,如果需要使用Servlet、Filter或Listener等Servlet API组件,可以使用@WebServlet、@WebFilter和@WebListener注解来定义它们,而不需要在web.xml文件中进行配置。但是,默认情况下,Spring Boot并不会自动扫描这些注解并将它们注册到Servlet容器中,需要使用@ServletComponentScan注解来启用自动注册功能。
3.@ServletComponentScan注解需要放置在Spring Boot应用程序的启动类上
这样,Spring Boot应用程序就可以自动扫描@WebServlet、@WebFilter和@WebListener注解,并将它们注册到Servlet容器中,使得这些Servlet API组件可以被正确地使用。
@ServletComponentScan @SpringBootApplication public class TakeAwayApplication { public static void main(String[] args) { SpringApplication.run(TakeAwayApplication.class, args); } }
3.编写Controller类EmployeeController
需要注意的是:@PostMapping里面的值
必须和资源文件recourse里面backend的api中的login.js中的url一致
@PostMapping("/employee/login")
public String login(HttpServletRequest request, @RequestBody Employee employee){
String username = employee.getUsername();
String password = employee.getPassword();
System.out.println("----username:"+username+"------password:"+password);
return "";
}
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。
@RestController和@Controller的区别如下:
1. @RestController注解是Spring4.0之后加入的注解,它是@Controller和@ResponseBody注解的结合体,用于表示这个类是用来处理RESTful请求的控制器,返回值将被直接写入HTTP响应正文中,常用于API接口的开发。
2. @Controller注解表示这个类是一个控制器,用于处理HTTP请求和响应,常用于页面的跳转和渲染。
3. @RestController注解的方法默认返回JSON格式的数据,而@Controller注解的方法默认返回页面或者视图。
4. @RestController注解的方法可以省略@ResponseBody注解,而@Controller注解的方法需要使用@ResponseBody注解来表示返回的是JSON数据。
5. @RestController注解可以直接使用@RequestMapping注解来处理HTTP请求,而@Controller注解需要使用@RequestMapping注解来映射请求路径,并且需要返回视图或者页面。
6. @RestController注解可以使用@GetMapping、@PostMapping等注解来处理HTTP请求,而@Controller注解需要使用@RequestMapping注解来处理不同的HTTP请求方法。
综上所述,@RestController注解适用于API接口的开发,而@Controller注解适用于页面的渲染和跳转。
@PostMapping和@GetMapping的区别如下:
-
@GetMapping注解用于处理HTTP GET请求,而@PostMapping注解用于处理HTTP POST请求。
-
@GetMapping注解的方法只能处理GET请求,而@PostMapping注解的方法只能处理POST请求。
-
@GetMapping注解的方法可以接收请求参数,但是请求参数只能通过URL传递,而@PostMapping注解的方法既可以通过URL传递请求参数,也可以通过请求体传递请求参数。
-
@GetMapping注解的方法不应该对数据进行修改,因为GET请求是幂等的,而@PostMapping注解的方法可以对数据进行修改,因为POST请求不是幂等的。
-
@GetMapping注解的方法可以缓存,因为GET请求是幂等的,而@PostMapping注解的方法不能缓存,因为POST请求不是幂等的。
综上所述,@GetMapping注解适用于获取数据的场景,而@PostMapping注解适用于创建、更新或删除数据的场景。
4config包中实现Webconfig类。
首先,先导入工具类JacksonObjectMapper。不然重写extendMessageConverters方法时会出现JacksonObjectMapper爆红。
5. 完善controller类。
相关MyBatis Plus知识:
MyBatis Plus中的QueryWrapper是一个条件构造器,用于构建查询条件。它可以通过链式调用的方式构建多个查询条件,支持等于、不等于、大于、小于、模糊查询、区间查询等多种查询方式。
使用QueryWrapper的步骤如下:
1. 创建QueryWrapper对象。
QueryWrapper<User> queryWrapper = new QueryWrapper<>();2. 使用QueryWrapper的方法构建查询条件,例如:
queryWrapper.eq("name", "张三") // 等于查询
.ne("age", 18) // 不等于查询
.gt("age", 20) // 大于查询
.lt("age", 30) // 小于查询
.like("name", "张") // 模糊查询
.between("age", 20, 30); // 区间查询
```3. 使用QueryWrapper作为参数调用MyBatis Plus的查询方法,例如:
List<User> userList = userMapper.selectList(queryWrapper);其中,userMapper是MyBatis Plus自动生成的Mapper接口,selectList是MyBatis Plus提供的查询方法。
除了以上方法外,QueryWrapper还支持多种查询方式,例如in、not in、isNull、isNotNull、orderBy等,可以根据具体的业务需求进行选择。
总之,QueryWrapper是MyBatis Plus中非常实用的一个工具,可以大大简化查询条件的构建过程,提高开发效率。
@RestController public class EmployeeController { @Autowired EmployeeService employeeService; /** * RequestBody可以解析jSON格式的数据,并且解析 */ @PostMapping("/employee/login") public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){ String username = employee.getUsername(); String password = DigestUtils.md5DigestAsHex(employee.getPassword().getBytes()); System.out.println("--1--username:"+username+"------password:"+password); /** * 返回结果是单张表,最好用实体类接受。即返回一个employee * 如果是交叉查询,则用List<Map> */ LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Employee::getUsername,username); Employee employee1=employeeService.getOne(queryWrapper); System.out.println("--2--username:"+employee1.getPhone()); if(employee1 == null){ return R.error("用户名或密码错误"); } if (!password.equals(employee1.getPassword())) { return R.error("密码错误,登陆失败,请重试!"); } if (employee1.getStatus()!=1) { return R.error("该账户被删除或禁用,登陆失败!"); } //讲员工的id放进session中 request.getSession().setAttribute("employee",employee1.getId()); return R.success(employee1); } }
R是服务器返回结果类。
@Data public class R<T> { private Integer code; //编码:1成功,0和其它数字为失败 private String msg; //错误信息 private T data; //数据 private Map map = new HashMap(); //动态数据 public static <T> R<T> success(T object) { R<T> r = new R<T>(); r.data = object; r.code = 1; return r; } public static <T> R<T> error(String msg) { R r = new R(); r.msg = msg; r.code = 0; return r; } public R<T> add(String key, Object value) { this.map.put(key, value); return this; } }
二、退出登陆操作
思想:点击退出,将登陆时保存的session消除掉。invalidate销毁全部session
三、过滤器功能
新建filter包,创建LoginCheckFilter类实现Filter的doFilter方法。
@WebFilter(filterName="LoginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String[] urlPermit=new String[] {
"/employee/login",
"/backend/**",
"/front/**"
};
//获取当前正在访问的URI
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestUri = request.getRequestURI();
// 判断是否是登录请求
// 如果是登录请求,放行
// 如果不是登录请求,判断是否是指定的URI
// 如果是指定的URI,放行
if ( check(requestUri, urlPermit)) {
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("-----免验证 当前正在访问的url-----"+requestUri);
return;
}
if(request.getSession().getAttribute("employee") != null){
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("-----放行 当前正在访问的url-----"+requestUri
+"-----当前用户:"+((Employee)request.getSession().getAttribute("employee")).getUsername());
return;
}
// 如果没有登录,重定向到登录页面
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.getWriter().write(JSON.toJSONString(R.error("没有登录")));
return;
}
public static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();
public boolean check(String requestUri,String[] arr_URL){
for (String item: arr_URL) {
boolean result = ANT_PATH_MATCHER.match(item, requestUri);
if (result) {
return true;
}
}
return false;
}
}