今天主要是在昨天的基础上完成用户管理、新闻类别以及新闻标签管理的相关内容。
1.用户管理
用户管理主要是登录、注销以及设置登录拦截器,当用户未登录时使其自动跳转到登录页面。
(1)登录拦截器
LoginIntercpter.java
package com.zhongruan.interceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor extends HandlerInterceptorAdapter
{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/admin");
return false;
}
return true;
}
}
WebConfig.java
package com.zhongruan.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin")
.excludePathPatterns("/admin/login");
}
}
(2)登录
登录主要是验证用户输入的密码和账号是否正确,其核心代码如下
@PostMapping("/login")
public String login(String username,
String password,
HttpSession session,
RedirectAttributes attributes) {
User user = userService.checkUser(username, password);
if (user != null) {
user.setPassword(null);
session.setAttribute("user", user);
return "admin/index";
} else {
// 重定向之后返回数据
attributes.addFlashAttribute("message", "用户名或者密码错误");
return "redirect:/admin";
}
}
(3)注销
注销是指用户退出系统后,系统删除用户的相关信息(存储在session的用户信息)。
核心代码如下:
@GetMapping("/logout")
public String logout(HttpSession session) {
session.removeAttribute("user");
return "redirect:/admin";
}
2.新闻类别管理
新闻类别管理主要就是其增删改查,其核心代码如下所示
@GetMapping("/types")
public String types(@PageableDefault(size = 5, sort = {"id"}, direction = Sort.Direction.DESC) Pageable pageable,
Model model) {
// pageable 前端封装好的分页对象 内部存放着相关的分页数据
// 查询所有的 分类对象
Page<Type> page = typeService.listType(pageable);
model.addAttribute("page", page);
return "admin/types";
}
@GetMapping("/types/input")
public String input(Model model) {
model.addAttribute("type", new Type());
return "admin/types-input";
}
// 校验功能 后端校验
@PostMapping("/types/add")
public String post(Type type, BindingResult result, RedirectAttributes attributes) {
// BindingResult 在type属性 绑定值
// 查找是否又同名的分类
Type t1 = typeService.getTypeByName(type.getName());
if (t1 != null) {
result.rejectValue("name", "nameError", "不能添加重复的类");
}
if (result.hasErrors()) {
return "admin/types-input";
}
// 如果没有错误 继续添加操作
Type t = typeService.save(type);
if (t == null) {
attributes.addFlashAttribute("message", "新增失败");
} else {
attributes.addFlashAttribute("message", "新增成功");
}
return "redirect:/admin/types";
}
@GetMapping("/types/{id}/delete")
public String delete(@PathVariable long id, RedirectAttributes attributes) {
// get请求中 参数的获取需要通过 @PathVariable
typeService.delete(id);
attributes.addFlashAttribute("message", "删除成功");
return "redirect:/admin/types";
}
// 更新的前置操作
@GetMapping("/types/{id}/toUpdate")
public String toUpdate(@PathVariable long id, Model model) {
// 得到需要修改的对象
Type type = typeService.getTypeById(id);
model.addAttribute("type", type);
return "admin/types-input";
}
// 更新操作
@PostMapping("/types/update/{id}")
public String update(long id, Type type, BindingResult bindingResult, RedirectAttributes attributes) {
// 1. 判断修改之后的名称是否重叠
Type t1 = typeService.getTypeByName(type.getName());
if (t1 != null) {
bindingResult.rejectValue("name", "nameErr", "该分类名称已存在");
}
if (bindingResult.hasErrors()) {
return "admin/types-input";
}
// 2. 更新操作
Type t2 = typeService.updateType(id, type);
if (t2 == null) {
attributes.addFlashAttribute("message", "更新失败");
} else {
attributes.addFlashAttribute("message", "更新成功");
}
return "redirect:/admin/types";
}
3.新闻标签管理
新闻标签管理同新闻类别管理一样,主要是其增删改查,相应核心代码如下
@GetMapping("/tags")
public String tags(@PageableDefault(size = 5, sort = {"id"}, direction = Sort.Direction.DESC) Pageable pageable,
Model model) {
model.addAttribute("page", tagService.listTag(pageable));
return "admin/tags";
}
// 新增前置
@GetMapping("/tags/input")
public String toAdd(Model model) {
model.addAttribute("tag", new Tag());
return "admin/tags-input";
}
// 新增操作
@PostMapping("/tags/add")
public String add(Tag tag, BindingResult result, RedirectAttributes attributes) {
Tag t1 = tagService.getTagByName(tag.getName());
if (t1 != null) {
result.rejectValue("name", "nameError", "不能添加重复的标签名");
return "admin/tags-input";
}
Tag t2 = tagService.save(tag);
if (t2 == null) {
attributes.addFlashAttribute("message", "新增失败");
} else {
attributes.addFlashAttribute("message", "新增成功");
}
return "redirect:/admin/tags";
}
4.总结
- 使用JPA,要新建一个数据访问持久层接口以继承JpaRepository
- JpaRepository集成了很多数据库,到时候直接调用就行,不用再去写sql语句。
- 对于复杂的操作,可以采用JPA的特有查询语句,或者用原生的sql语句也行。
- 拦截器可以拦截请求,因此可用用来做一些验证工作或者一些统一工作,如设置编码等等。