SpringBoot快速入门3---上手简单项目

文章目录

首页实现

@RequestMapping({"/", "/index.html"})
public String index() {
    return "login";
}
  • 注意导入thymeleaf,变更页面匹配thymeleaf语法
  • 静态资源最好使用thymeleaf接管,@{/}

国际化

  • 步骤:

    1. 编写国际化配置文件,抽取页面需要显示的国际化消息
      SpringBoot快速入门3---上手简单项目

    2. springboot自动配置好了管理国际化资源文件的组件,只需要在配置文件中修改值即可

      # 国际化配置文件的路径
      spring.messages.basename=i18n.login
      
    3. thymeleaf获取国际化信息值th:text="#{login.find}th:placeholder="#{login.email}"

点击按钮切换语言信息

  • 原理:国际化Locale(区域信息对象),LocaleResolver(获取区域信息对象)

    @Bean
    //容器中没有localeResolver这个bean的时候使用,也就是说用户写了的话不会生成
    @ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME)
    @SuppressWarnings("deprecation")
    //这个默认的区域信息解析器是根据请求头带来的区域信息获取Locale进行国际化
    public LocaleResolver localeResolver() {
       if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) {
          return new FixedLocaleResolver(this.webProperties.getLocale());
       }
       if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
          return new FixedLocaleResolver(this.mvcProperties.getLocale());
       }
       AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
       Locale locale = (this.webProperties.getLocale() != null) ? this.webProperties.getLocale()
             : this.mvcProperties.getLocale();
       localeResolver.setDefaultLocale(locale);
       return localeResolver;
    }
    
  • 点超链接后重新转到当前页面

    <a th:href="@{/index.html(l='zh_CN')}">中文</a>
    <a th:href="@{/index.html(l='en_US')}">English</a>
    
  • 自己写一个区域信息解析器

    public class MyLocaleResolver implements LocaleResolver {
    
        @Override
        public Locale resolveLocale(HttpServletRequest httpServletRequest) {
            //获取前端传来的值
            String l = httpServletRequest.getParameter("l");
            //初始化为默认
            Locale locale = Locale.getDefault();
            if(!StringUtils.isEmpty(l)){
                String[] split = l.split("_");
                locale = new Locale(split[0], split[1]);
            }
            return locale;
        }
    
  • 把写好的解析器放入到spring容器

    @Configuration
    public class MyMvcConfig {
    
        @Bean
        //注意!!因为要保证只存在我们写的localeResolver,所以bean名称只能为localeResolver
        public LocaleResolver localeResolver() {
            return new MyLocaleResolver();
        }
    
    }
    

登录功能实现

  • 登录表单

    <form class="form-login" th:action="@{/user/login}">
        <h2 class="form-login-heading" th:text="#{login.tip}">请登录</h2>
        <!--这里判断msg是否为空,虽然没必要,但了解一下怎么写-->
        <p style="color: red;text-align: center" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
        <div class="login-wrap">
            <input type="text" name="username" class="form-control" th:placeholder="#{login.username}" autofocus>
            <br>
            <input type="password" name="password" class="form-control" th:placeholder="#{login.password}">
    
  • 编写controller

    @RequestMapping("/user/login")
    public String login(
        @RequestParam("username") String username,
        @RequestParam("password") String password,
        Model model){
        if (!StringUtils.isEmpty(username) && "123456".equals(password)){
            return "redirect:/index";
        }else {
            model.addAttribute("msg","用户名或者密码错误");
            return "login";
        }
    }
    
    @RequestMapping("index")
    public String index(){
        return "index";
    }
    

拦截器功能实现

  • 实现拦截器方法

    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.html").forward(request, response);
                //没登录,拦截
                return false;
            } else {
                return true;
            }
        }
    }
    
  • 配置拦截器

    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //所有请求都拦截,再排除一些请求
            registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
                    .excludePathPatterns("/index.html", "/", "/user/login", "/assets/**", "/css/**", "/img/**", "/js/**");
        }
        
    }
    

员工表展示

  • 实现导航栏、侧边栏等构建的重用

    <!--可重用组件加上th:fragment="menu"-->
    <aside th:fragment="menu">
    <!--其他页面放入组件,需要标识组件所在的页面-->
    <div th:replace="~{index.html :: menu}"></div>
    
  • js实现侧边栏获取点击状态(有瑕疵)

    <script th:src="@{/js/menu.js}"></script>
    <script type="text/javascript" th:inline="javascript">
        msg('table');
    </script>
    
    • menu.js

      function msg(message) {
          //根据传参(id)获取需要改变class的标签
          $("#" + message).attr("class", "active");
          let li = $("#" + message + "_li");
          //如果id存在
          if(li.length>0){
              li.attr("class", "active");
          }
      }
      
  • thymeleaf实现侧边栏获取点击状态

    • 在调用语句里传参

      <div th:replace="~{index.html :: menu(active = 'table')}"></div>
      
    • 被调用语句中获取参数并进行判断

      <li th:class="${active=='table'} ? 'active'"><a th:href="@{/employees}">Basic Table</a></li>
      
  • controller

    private EmployeeDAO employeeDAO;
    
    @Autowired
    public void setEmployeeDAO(EmployeeDAO employeeDAO) {
        this.employeeDAO = employeeDAO;
    }
    
    @RequestMapping("/employees")
    public String list(Model model){
        Collection<Employee> employees = employeeDAO.getAll();
        model.addAttribute("employees", employees);
        return "basic_table";
    }
    
  • 获取和展示信息

    <thead>
    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>邮箱</th>
        <th>性别</th>
        <th>部门</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="employee : ${employees}">
        <td th:text="${employee.getId()}"></td>
        <td th:text="${employee.getLastName()}"></td>
        <td th:text="${employee.getEmail()}"></td>
        <!--判断,符合条件则有效-->
        <td th:if="${employee.getGender()} == 1">男</td>
        <td th:if="${employee.getGender()} == 0">女</td>
        <!--或者-->
        <td th:text="${employee.getGender()==0?'女':'男'}"></td>
        
      <td th:text="${employee.getDepartment().getDepartmentName()}"></td>
        <!--日期处理-->
        <td th:text="${#dates.format(employee.getBirth(),'yyyy-mm-dd')}"></td>
    </tr>
    

实现ajax和分页

  • 页面中调用ajax

    <script type="text/javascript" th:inline="javascript">
        //第一个参数为当前页数,第二个参数为ajax请求url
        tableAjax(page, [[@{/}]]+'employeesAjax');
    </script>
    
  • ajax.js

    function tableAjax(page, url) {
        $.ajax({
            url: url,
            //给后端传当前页面,用于分页
            data: {"page": page},
            success: function (employees) {
                //显示和隐藏上一页、下一页,用于分页
                if (page > 1) {
                    $("#up").show();
                } else{
                    $("#up").hide();
                }
                if (page >= employees.length / 2) {
                    $("#down").hide();
                } else{
                    $("#down").show();
                }
    
                let html = null;
                for (let i = 0; i < employees.length; i++) {
                    if(employees[i].gender === 1){
                        gender = '男';
                    }else{
                        gender = '女';
                    }
                    html += "<tr>" +
                        "<td>" + employees[i].id + "</td>" +
                        "<td>" + employees[i].lastName + "</td>" +
                        "<td>" + employees[i].email + "</td>" +
                        "<td>" + employees[i].gender + "</td>" +
                        "<td>" + employees[i].department.departmentName + "</td>" +
                        "<td>" + employees[i].birth + "</td>" +
                        "</tr>";
                }
                $("#table").html(html);
                $("#page").text(page);
            }
        });
    }
    
  • 分页

    <div>
        <!--显示当前页面-->
        <span id="page" th:text="${page}"></span>
        <a id="up" hidden onclick="pagedown()">上一页</a>
        <a id="down" onclick="pageup()">下一页</a>
        <script type="text/javascript" th:inline="javascript">
            let page = [[${page}]];
    
            function pageup() {
                page += 1;
                tableAjax(page, [[@{/}]]+'employeesAjax');
            }
            function pagedown() {
                page -= 1;
                tableAjax(page, [[@{/}]]+'employeesAjax');
            }
        </script>
    </div>
    
  • controller

    @RequestMapping("/employees")
    public String list(Model model){
        Collection<Employee> employees = employeeDAO.getAll();
        model.addAttribute("employees", employees);
        model.addAttribute("page",1);
        return "basic_table";
    }
    
    @RequestMapping("/employeesAjax")
    @ResponseBody
    public Collection<Employee> employeesAjax(int page){
        //返回的java对象springboot集成的jackson会自动帮我们解析成json对象并传输给前端
        return employeeDAO.getAll(page);
    }
    

一对多前端传值

  • 当后端需要一个对象参数,且该对象内包含其他对象时

    public class Employee {
        private Integer id;
        private String lastName;
        private String email;
        private Integer gender; //0:女 1:男
        private Department department;
        private Date birth;
    
    //例如
    public String addEmployee(Employee employee) {
    
  • 前端可以这样传值

    <!--用对象.对象的属性作为参数名即可-->
    <select name="department.id"></select>
    <!--一般情况直接用对象的属性名传参即可-->
    <input type="text" name="lastName">
    
    • 猜测一下大概原理,mvc会获取到form提交的所有name和对应的值,然后每个name找对应的controller方法的参数并赋值,如果name里面有.的话就会查找对应对象里的属性,例如department.id,会先判断出department是所需对象参数的类的属性,然后再在department对象中找id属性

员工增加更新删除

  • 增加controller

    @RequestMapping("/toAdd")
    public String toUpdate(Model model) {
        //获取所有部门,用于下拉框选择部门
        Collection<Department> departments = departmentDAO.getDepartments();
        model.addAttribute("departments", departments);
        return "add_table";
    }
    
    @RequestMapping("/addEmployee")
    public String addEmployee(Employee employee) {
        System.out.println(employee);
        employeeDAO.save(employee);
        return "redirect:/employees";
    }
    
  • 更新html

    <form class="form-horizontal style-form" role="form" th:action="@{/updateEmployee}" method="post">
        <input hidden name="id" th:value="${employee.getId()}">
        <div class="form-group">
            <label class="col-sm-1 control-label">姓名</label>
            <div class="col-sm-8">
                <input type="text" class="form-control" name="lastName" th:value="${employee.getLastName()}">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">邮箱</label>
            <div class="col-sm-8">
                <input type="email" class="form-control" id="text3" name="email" th:value="${employee.getEmail()}">
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">性别</label>
            <div class="col-sm-8">
                <div class="radio">
                    <label>
                        <input type="radio" name="gender" value="1" th:checked="${employee.getGender() == 1}">
                        男
                    </label>
                    <label>
                        <input type="radio" name="gender" value="0" th:checked="${employee.getGender() == 0}">
                        女
                    </label>
                </div>
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">部门</label>
            <div class="col-sm-8">
                <label>
                    <select class="form-control" name="department.id" style="margin: 5px 0 0 0">
                        <option th:selected="${dept.getId()==employee.getDepartment().getId()}" th:each="dept : ${departments}"
                                th:text="${dept.getDepartmentName()}"
                                th:value="${dept.getId()}">
                        </option>
                    </select>
                </label>
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-1 control-label">生日</label>
            <div class="col-sm-8">
                <input type="text" class="form-control">
            </div>
        </div>
        <button type="submit" class="btn btn-theme">Sign in</button>
    </form>
    
  • 更新controller

    @RequestMapping("/toUpdate/{id}")
    public String toUpdate(@PathVariable("id") Integer id, Model model) {
        //根据获取的员工id获取员工所有信息并传给前端
        Employee employee = employeeDAO.getEmployeeByID(id);
        Collection<Department> departments = departmentDAO.getDepartments();
        model.addAttribute("departments", departments);
        model.addAttribute("employee", employee);
        return "update_table";
    }
    
    @RequestMapping("/updateEmployee")
    public String updateEmployee(Employee employee) {
        employeeDAO.update(employee);
        return "redirect:/employees";
    }
    
  • 删除controller

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

错误页面

  • 404等错误页面定制,只需要在该目录下创建对应的html,404.html、500.html等
    SpringBoot快速入门3---上手简单项目

退出登录

@RequestMapping("/user/logout")
public String logout(HttpSession session){
    //清除当前session对象
    session.invalidate();
    return "redirect:/";
}
上一篇:MySql基础查询-分组函数


下一篇:MySql基础查询-流程控制函数