SpringBoot学习(四)———— MVC配置原理、实现简单的功能、页面国际化、登录拦截、抽取组件/循环/判断、增删查改

MVC配置原理

修改SpringBoot的默认配置:SpringBoot在自动配置组件时,先看容器中有没有用户自己的配置,如果有就用用户自己配置的,如果没有就用容器的自动配置,有些组件可以存在多个,会将默认配置和用户配置组合使用

自定义配置类

编写一个@Configuration注释的注解类,实现WebMvcConfigurer,还不能标注@EnableWebMvc

//扩展视图解析器
@Configuration//如果想自定义功能,可以通过这个组件,将它交给springboot,springboot会帮我们实现自动装配
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //自己设置跳转路径,以及跳转的页面
        registry.addViewController("/aaa").setViewName("test");
    }

    //    @Bean
//    public ViewResolver myViewResolver() {
//        return new MyViewResolver();
//    }
//
//    //自定义自己的视图解析器
//    public static class MyViewResolver implements ViewResolver {
//        @Override
//        public View resolveViewName(String s, Locale locale) throws Exception {
//            return null;
//        }
//    }
}

在SpringBoot中,有非常多的xxxConfiguration帮助我们进行扩展,只要看见了这个东西,我们就要注意了

实现简单的功能

首页配置,所有页面的静态资源都要有thymeleaf接管@{}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lpwhHjk5-1627978330160)(SpringBoot.assets/image-20210728083229058.png)]

#手动修改路径
server:
  servlet:
    context-path: /wjq

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZUtbydLT-1627978330161)(SpringBoot.assets/image-20210728083317344.png)]

页面国际化

th:action="@{/user/login}"涉及url

th:text="#{login.username}"页面国际化,涉及配置文件

即根据自己的需要实现中英文的切换

  1. 配置i18n文件
  2. 如果需要在项目中按钮自动切换,需要自定义组件LocaleResolver
  3. 记得将自己的组件配到SpringBoot中 @Bean

自定义设置请求头的语言

public class MyLocaleResolver implements LocaleResolver {

    //可以用来设置请求头的language
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //获取前端的参数
        String parameter = httpServletRequest.getParameter("l");
        //获取默认时区地址
        Locale locale = Locale.getDefault();
        if (!StringUtils.isEmpty(parameter)) {
            String[] split = parameter.split("_");
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
    }
}

记得注入到SpringBoot中(此文件用来存放自己的MvcConfig)

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    //手动设置首页跳转
    public void addViewControllers(ViewControllerRegistry registry) {
        //首页
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index").setViewName("index");
        //主页,当我们接收到了main.html时,会去找show,此时boot会背囊我们完成在template下的拼接
        registry.addViewController("/main.html").setViewName("show");
    }
    //将Bean进行注册入springBoot中(作用,中英文切换)
    @Bean
    public LocaleResolver localeResolver(){//这个名字貌似必须为localeResolver
        return new MyLocaleResolver();
    }
}

编写i18n配置文件,即国际化语言,可以实现中文和英文

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAiAd3Cy-1627978330163)(SpringBoot.assets/image-20210728142805462.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aQyxHjPj-1627978330164)(SpringBoot.assets/image-20210728142817945.png)]

首页编写

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
<!--    通过thymeleaf引入bootstrap   链接地址@{}-->
    <link th:href="@{/css/bootstrap.min.js}">
</head>
<body>
<h1>这是登录首页</h1>
<form th:action="@{/user/login}" method="post">
<!--    配置文件的参数   #{}-->
    <label th:text="#{login.tip}">Please sign in</label><br>
<!--通过th:text表示展示的内容                          判断语句,判断msg字符串不为空   可以将!换为not-->
    <label th:text="${msg}" style="color: red" th:if="${! #strings.isEmpty(msg)}"></label><br>
    
    <label th:text="#{login.username}">Username</label>
    <input type="text" th:placeholder="#{login.username}" name="username"><br>
    <label th:text="#{login.password}">Password</label>
    <input type="text" th:placeholder="#{login.password}" name="password"><br>
<!--    像checkbox、submit这些本身就不用写什么值,因此不存在th:text这类属性,我们可以通过行内字符来写[[]]-->
    <input type="checkbox">[[#{login.remember}]]<br>
    <button type="submit">[[#{login.btn}]]</button>
    <br>
<!--    会有自动拼接-->
    <a th:href="@{/index(l='zh_CN')}">中文</a><br>
    <a th:href="@{/index(l='en_US')}">English</a>
</form>
</body>
</html>

登录拦截

拦截器三个方法:

preHandler

  1. 调用controller之前
  2. 若返回false,则中断执行,不会执行AfterCompletion
  3. 链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行

PostHandler

  1. preHandler返回true
  2. 在执行完controller之后,因此可以对modelAndView进行操作
  3. 链式Intercepter情况下,Intercepter按照声明的顺序倒着执行

AfterCompletion

  1. preHandler返回true
  2. DispatcherServlet进行渲染之后
  3. 多用于清理资源

MyMvcConfig

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns("/index","/","/user/login","/css/**");
}

LoginController

@Controller
public class LoginController {
    @RequestMapping("/user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model, HttpSession session) {
//        空和null都会判断
        if (!StringUtils.isEmpty(username) && "123".equals(password)) {//登录成功
            session.setAttribute("loginUser", username);
            return "redirect:/main.html";
        }else {
            model.addAttribute("msg", "用户名或密码错误!");
            return "index";
        }
    }
}

LoginHandlerInteceptor

//登录拦截器
public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登录成功后,将用户存入session中
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            request.setAttribute("msg", "没有权限,请先登录");
            request.getRequestDispatcher("/index").forward(request, response);
            return false;
        }else {
            return true;
        }
    }
}

抽取组件/循环/判断

th:fragment="sidebar"

th:replace="~{common/commons::sidebar}"

th:insert="~{show::sidebar}"

抽取出来的公共组件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t8UOKZ7w-1627978330165)(SpringBoot.assets/image-20210729133926422.png)]

<body>
<!--方法二:我们创建一个commons用来将所有的公共页面进行抽取,然后将抽取的部分用insert/replace进行一个插入-->
<!--div展示-->
<div style="height: 50px; width: 50%; border:1px black solid" th:fragment="sidebar"></div>
</body>

引入组件

<!--    引入公共组件-->
    <div th:replace="~{common/commons::sidebar}"></div>

循环/判断/组件传参

<body>
<!--插入show.html中的sidebar-->
<!--insert和replace实现的功能一样,但是二者的含义不一样-,一个是嵌套,一个是直接替换-->
<!--<div th:insert="~{show::sidebar}"></div>-->

<!--组件传参-->
<div th:replace="~{common/commons::sidebar(active='list.html')}"></div>
<table>
    <thead>
    <tr>
        <th>id</th>
        <th>lastName</th>
        <th>email</th>
        <th>gender</th>
        <th>department</th>
        <th>birth</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
      <!--  thymeleaf循环-->
    <tr th:each="emp:${emps}}">
        <td th:text="${emp.getId()}"></td>
        <td th:text="${emp.getLastName()}"></td>
        <td th:text="${emp.getEmail()}"></td>
        <!--判断-->
        <td th:text="${emp.getGender()==0?'':''}"></td>
        <td th:text="${emp.department.getDepartment()}"></td>
<!--        thymeleaf中对java.util.Date中做的工具类#dates-->
        <!--时间格式化-->
        <td th:text="${#dates.format(emp.getBirth(),yyyy-MM-dd HH:mm:ss}}"></td>
        <td >
            <button>编辑</button>
            <button>删除</button>
        </td>
    </tr>
    </tbody>
</table>
</body>

组件接收参数

<!--判断组件传的参数,进行高亮的显示-->
<a th:href="@{/emps}" th:class="${active=='list.html'?'nav-link active':'nav-link'}">员工展示</a>
<a th:href="@{/index}">返回登录页</a>

增删查改

add.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>添加员工</title>
</head>
<body>
<form th:action="@{/addEmp}" method="post">
    id:<input type="text" name="id"><br>
    lastName:<input type="text" name="lastName"><br>
    email:<input type="text" name="email"><br>
    gender:
    <input type="radio" name="gender" value="1"><input type="radio" name="gender" value="0"><br>
    department:
    <select name="department.id">
        <option th:each="dept:${departments}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
    </select><br>
    birth:
    <input type="text" name="birth"><br>
    <button type="submit">添加</button>
</form>
</body>
</html>

list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>列表</title>
</head>
<body>
<!--插入show.html中的sidebar-->
<!--insert和replace实现的功能一样,但是二者的含义不一样-,一个是嵌套,一个是直接替换-->
<!--<div th:insert="~{show::sidebar}"></div>-->

<!--组件传参-->
<!--<div th:replace="~{common/commons::sidebar(active='list.html')}"></div>-->
<a th:href="@{/toAdd}">添加员工</a>
<a th:href="@{/logout}">注销</a>
<table>
    <thead>
    <tr>
        <th>id</th>
        <th>lastName</th>
        <th>email</th>
        <th>gender</th>
        <th>department</th>
        <th>birth</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="emp:${employees}">
        <td th:text="${emp.getId()}"></td>
        <td th:text="${emp.getLastName()}"></td>
        <td th:text="${emp.getEmail()}"></td>
        <td th:text="${emp.getGender()==0?'':''}"></td>
        <td th:text="${emp.department.getDepartmentName()}"></td>
<!--        thymeleaf中对java.util.Date中做的工具类#dates-->
        <td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}"></td>
        <td >
<!--            传参-->
            <a th:href="@{/update/}+${emp.getId()}">编辑</a>
            <a th:href="@{/delete/}+${emp.getId()}">删除</a>
        </td>
    </tr>
    </tbody>
</table>
</body>
</html>

update.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>修改页面</title>
</head>
<body>
<form th:action="@{/realUpdate}" method="post">
    <input type="hidden" name="id" th:value="${emp.getId()}"><br>
    lastName:<input type="text" name="lastName" th:value="${emp.getLastName()}"><br>
    email:<input type="text" name="email" th:value="${emp.getEmail()}"><br>
    gender:
    <input type="radio" name="gender" value="1" th:checked="${emp.getGender()==1}"><input type="radio" name="gender" value="0" th:checked="${emp.getGender()==0}"><br>
    department:
    <select name="department.id">
        <option th:each="dept:${depts}" th:selected="${dept.getId()}==${emp.getDepartment().getId()}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
    </select><br>
    birth:
    <input type="text" name="birth" th:value="${emp.getBirth()}"><br>
    <button type="submit">修改</button>
</form>
</body>
</html>

EmployeeController

@Controller
public class EmployeeController {
    @Autowired
    private EmployeeRepository employeeRepository;
    @Autowired
    private DepartmentRepository departmentRepository;

    @RequestMapping("/emps")
    public String getAll(Model model) {
        Collection<Employee> employees = employeeRepository.query();
        model.addAttribute("employees", employees);
        return "/emp/list";
    }

    @GetMapping("/toAdd")
    public String toAdd(Model model) {
        //获取所有部门
        Collection<Department> departments = departmentRepository.getAllDep();
        model.addAttribute("departments", departments);
        return "emp/add";
    }

    @PostMapping("/addEmp")
    public String addEmp(Employee employee) {
        //添加的操作
        employeeRepository.add(employee);
        Integer id = employee.getDepartment().getId();
        Department dept = departmentRepository.getDepById(id);
        employee.getDepartment().setDepartmentName(dept.getDepartmentName());
        return "redirect:/emps";
    }

//    @RequestMapping("/toUpdatePage")
//    public String toUpdatePage() {
//        return "emp/update";
//    }

    @RequestMapping("/update/{id}")
    public String update(@PathVariable("id") Integer id, Model model) {
        Employee emp = employeeRepository.queryById(id);
        model.addAttribute("emp", emp);
        Collection<Department> depts = departmentRepository.getAllDep();
        model.addAttribute("depts", depts);
        return "emp/update";
    }

    @RequestMapping("/realUpdate")
    public String realUpdate(Employee employee) {
        employeeRepository.add(employee);//修改和增加都可以实现
        Integer id = employee.getDepartment().getId();
        Department dept = departmentRepository.getDepById(id);
        employee.getDepartment().setDepartmentName(dept.getDepartmentName());
        return "redirect:/emps";
    }

    @RequestMapping("/delete/{id}")
    public String delete(@PathVariable("id") Integer id) {
        employeeRepository.delete(id);
        return "redirect:/emps";
    }

    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate();
//        return "redirect:/main";//会有没有权限的提示
        return "redirect:/index";//直接返回首页
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值