zoukankan      html  css  js  c++  java
  • spring boot 尚桂谷学习笔记05 ---Web

    ------web 开发登录功能------

      修改login.html文件:注意加粗部分为 msg 字符串不为空时候 才进行显示

    <!DOCTYPE html>
    <!-- saved from url=(0050)http://getbootstrap.com/docs/4.0/examples/sign-in/ -->
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta name="description" content="">
        <meta name="author" content="">
        <link rel="icon" href="http://getbootstrap.com/favicon.ico">
    
        <title>Signin Template for Bootstrap</title>
    
        <!-- Bootstrap core CSS -->
        <link href="/asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
    
        <!-- Custom styles for this template -->
        <link href="/asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">
      </head>
    
      <body class="text-center">
        <form class="form-signin" th:action="@{/user/login}" method="post">
          <img class="mb-4" src="/asserts/img/bootstrap-solid.svg" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72">
          <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
          <p style="color: red;" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
          <label for="username" class="sr-only" th:text="#{login.username}">Email address</label>
          <input name="username" type="email" id="username" th:placeholder="#{login.username}" class="form-control" placeholder="Email address" required="" autofocus="">
          <label for="inputPassword" th:text="#{login.password}" class="sr-only">Password</label>
          <input name="password" type="password" th:placeholder="#{login.password}" id="inputPassword" class="form-control" placeholder="Password" required="">
          <div class="checkbox mb-3">
            <label>
              <input type="checkbox" value="remember-me"/> [[#{login.remember}]]
            </label>
          </div>
          <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
          <p class="mt-5 mb-3 text-muted">© 2017-2018</p>
            <a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
            <a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
        </form>
    </body></html>

      添加一个controller 对应页面跳转

    package com.lixuchun.springboot.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import java.util.Map;
    
    @Controller
    public class LoginController {
    
        // @RequestMapping(value = "/user/login", method = RequestMethod.POST)
        @PostMapping(value = "/user/login")
        public String login(@RequestParam String username, @RequestParam String password
                ,Map<String, Object> map) {
            if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
                // 登录成功
                return "dashboard";
            } else {
                map.put("msg", "用户登录失败!");
                // 登录失败
                return "login";
            }
        }
    }

      实现效果:填写正确情况下跳转到 dashboard.html页面中,错误情况下 返回login页面 并且显示 用户登录失败!

      登录 开发期间模板引擎页面修改以后要实时生效

        禁用模板引擎缓存:spring.thymeleaf.cache=false

        修改页面完成以后 ctrl + f9 重新编译

      当页面位于 dashboard 页面 按 F5 会有是否表单再次提交提示 (表单重复提交)

        可以进行重定向防止重复提交

         if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
                // 登录成功
                // 防止表单从夫提交 可以从定向导主页
                return "redirect:/main.html";
            } else {
                map.put("msg", "用户登录失败!");
                // 登录失败
                return "login";
            }

        修改Mvc View视图解析器

        @Bean
        public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
            WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
                @Override
                public void addViewControllers(ViewControllerRegistry registry) {
                    registry.addViewController("/").setViewName("login");
                    registry.addViewController("/index.html").setViewName("login");
                    registry.addViewController("/main.html").setViewName("dashboard");
                }
            };
            return adapter;
        }

      如果这样修改了 直接访问 localhost:8080/main.html 就可以直接访问 登录功能没起到作用 那么引入拦截器

      拦截器 编写拦截器controller 必须实现 HandlerInterceptor

      pre 在登录之前进行检查:

    package com.lixuchun.springboot.component;
    
    import org.springframework.lang.Nullable;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 进行登录检查
     */
    public class LoginHandlerIntercepter implements HandlerInterceptor{
    
        // 目标方法预检查
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Object user = request.getSession().getAttribute("loginUser");
            if (user == null) {
                // 未登录 返回登录页面
                request.setAttribute("msg", "没有用户权限 请先登录");
           // 没有登录跳转到 /index.html 页面 request.getRequestDispatcher(
    "/index.html").forward(request, response); return false; } else { // 已经登录 放行请求 return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }

      Mvc 配置文件添加 Interceptor 组件 进行注册:

        @Bean
        public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
            WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
                @Override
                public void addViewControllers(ViewControllerRegistry registry) {
                    registry.addViewController("/").setViewName("login");
                    registry.addViewController("/index.html").setViewName("login");
                    registry.addViewController("/main.html").setViewName("dashboard");
                }
    
                // 注册拦截器
                @Override
                public void addInterceptors(InterceptorRegistry registry) {
                    // 拦截任意请求
                    // 已经做好了静态资源的映射 *.css *.js 访问等 不需要做处理
                    registry.addInterceptor(new LoginHandlerIntercepter()).addPathPatterns("/**")
                        .excludePathPatterns("/index.html", "/", "/user/login");
                }
            };
            return adapter;
        }

      访问效果:在没有登录的情况下 访问 localhost:8080/main.html

      登录后再次访问:左侧上面 test@test.com 为登录名称 dashboard 页面 [[${session.loginUser}]] 行内表达式取值

      CRUD-员工列表 

      实验要求: 

        1) RestfulCRUD: CRUD 满足Rest风格

        URI : /资源名称/资源标识  HTTP请求方式区分对资源的CRUD操作

           /emp/{id}

        

        2). 实验的请求架构

        

        

        3).员工列表

          抽取公共元素片段

            <div th:fragment="copy">&COPY 2011 thymes Virtual Grocery</div>

          引入公共元素片段

            <div th:insert="~{footer::copy}"></div>

            ~{templatename::selector} :模板名 :: 选择器

            ~{templatename::fragmentname}:模板名::片段名

          三种引入公共片段th属性:

            th:insert :将公共的片段整个插入到声明引用的div中

            th:replace: 将声明引入的元素替换为公共片段

            th:include:被引入的片段内容包含近这个标签中

            如果使用th:insert 等属性进行引入 可以不用写 ~{} 

            行内写法加上 [[~{}]] , [(~{})] (转义不转义)

          dashboard 页面定义公共片段头 th:fragment="topbar"

    <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
          <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
          <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
          <ul class="navbar-nav px-3">
            <li class="nav-item text-nowrap">
              <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
            </li>
          </ul>
        </nav>

          list 页面头取法 

    <!-- 引入抽取的topbar -->
    <!-- 模板名称:使用thymeleaf的配置规则进行解析 -->
    <div th:replace="~{dashboard::topbar}"></div>

          dashboard 页面定义公共片段侧边栏 id="sideBar"

        <nav id="sideBar" class="col-md-2 d-none d-md-block bg-light sidebar" style="margin-top: 50px;">
              <div class="sidebar-sticky">
                <ul class="nav flex-column">
                  <li class="nav-item">
                    <a class="nav-link active" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
                      Dashboard <span class="sr-only">(current)</span>
                    </a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
                      Orders
                    </a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
                      Products
                    </a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#" th:href="@{/emps}">
                      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
                      员工管理
                    </a>
                  </li>
                </ul>
              </div>
            </nav>

          list 页面侧边栏取法

    <!-- 引入侧边栏 -->
    <div th:replace="~{dashboard::#sideBar}"></div>

        也可以单独提出一个bar文件 然后在各个页面进行调用

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <!-- top bar -->
        <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
            <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
            <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
            <ul class="navbar-nav px-3">
                <li class="nav-item text-nowrap">
                    <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
                </li>
            </ul>
        </nav>
    
        <!-- side bar -->
        <nav id="sideBar" class="col-md-2 d-none d-md-block bg-light sidebar" style="margin-top: 50px;">
            <div class="sidebar-sticky">
                <ul class="nav flex-column">
                    <li class="nav-item">
                        <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
                            Products
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#" th:href="@{/emps}">
                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
                            员工管理
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layers"><polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
                            Integrations
                        </a>
                    </li>
                </ul>
            </div>
        </nav>
    </body>
    </html>

        页面进行调用 list 页面 效果和之前的效果一样

    <!-- 引入抽取的topbar -->
    <!-- 模板名称:使用thymeleaf的配置规则进行解析 -->
    <div th:replace="commons/bar::topbar"></div>
    <!-- 引入侧边栏 -->
    <div th:replace="commons/bar::#sideBar"></div>

        

      引入片段也可以传入参数:

        在 dashboard.html 页面引入左侧栏时候 传入参数

    <div th:replace="commons/bar::#sideBar(activeUri='main.html')"></div>

        在 bar.html 页面设置左侧栏时候 通过传过来的参数设置 是否高亮

    <li class="nav-item">
      <a class="nav-link active" href="#"
          th:href="@{/main.html}" th:class="${activeUri=='main.html'?'nav-link active':'nav-link'}">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
              Dashboard <span class="sr-only">(current)</span>
        </a>
    </li>        

       

      员工列表做数据展示:

      list.html 页面编写

        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
          <
    div class="chartjs-size-monitor" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;">
            <
    div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
            <
    div style="position:absolute;1000000px;height:1000000px;left:0;top:0"></div>
            </
    div>
              <
    div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
                <
    div style="position:absolute;200%;height:200%;left:0; top:0">
              </
    div>
            </
    div>
          </
    div> <h2><button class="btn btn-sm btn-success">员工添加</button></h2> <h2>Section title</h2> <div class="table-responsive"> <table class="table table-striped table-sm"> <thead> <tr> <th>#</th> <th>lastName</th> <th>email</th> <th>gender</th> <th>department</th> <th>birth</th> <th>options</th> </tr> </thead> <tbody> <tr th:each="emp:${emps}"> <td th:text="${emp.id}"></td> <td>[[${emp.lastName}]]</td> <td th:text="${emp.email}"></td> <td th:text="${emp.gender}==0?'girl':'boy'"></td> <td th:text="${emp.department.departmentName}"></td> <td th:text="${#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')}"></td> <td> <button class="btn btn-sm btn-primary">编辑员工</button> <button class="btn btn-sm btn-danger">删除员工</button> </td> </tr> </tbody> </table> </div> </main>

      做一个伪处理 employeeDao 

    package com.lixuchun.springboot.dao;
    
    import com.lixuchun.springboot.entities.Department;
    import com.lixuchun.springboot.entities.Employee;
    import org.springframework.stereotype.Repository;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    @Repository
    public class EmployeeDao {
        public Employee selectEmpById(Integer id) {
            return new Employee();
        }
    
        public List<Employee> selectEmps() {
            List<Employee> empList = new ArrayList<Employee>();
            for (int i = 0; i < 6; i++) {
                Employee emp = new Employee(i, "emp" + i,
                        i + "emp@emp.com", 0,
                        new Department(i, "dep"+ i), new Date());
                empList.add(emp);
            }
            return empList;
        }
    }

      employee / department

    department
        private Integer id;
        private String departmentName;
    
    employee
        id
        lastName
        email
        gender
        department
        birth

      EmpController 编写

        @Autowired
        EmployeeDao employeeDao;
    
        // 查询所有员工返回列表页面
        @GetMapping("/emps")
        public String list(Model model) {
            List<Employee> employees = employeeDao.selectEmps();
            model.addAttribute("emps", employees);
            // classpath:/templates/xxx.html
            return "emp/list";
        }

      最后页面效果:

      员工添加功能:

        list 添加按钮  <a class="btn btn-sm btn-success" href="emp" th:href="@{/emp}">员工添加</a>

        emp get 请求到员工添加页面

        emp post 添加员工

      

      其中部门为后台查出来的,前后台处理

     

    <select class="form-control">
        <option th:value="${dept.id}" th:each="dept:${depts}" th:text="dept.departmentName"></option>
    </select>

      点击添加按钮 post 到 emp为添加功能

    <form ah:action="@{/emp}" method="post">

      员工添加controller

      修改日期格式:spring.mvc.date-format=yyyy-MM-dd

      员工修改:emp/id ------->get 方式

    <a class="btn btn-sm btn-primary" th:href="@{/emp/} + ${emp.id}">编辑员工</a>

      页面需要回显:

        th:value="${emp!=null}?${emp.lastName}">

        th:checked="${emp!=null}?${emp.gender==1}" / gender==0

        th:selected="${emp!=null}?${dept.id==emp.department.id}"

      如何发送put请求,到员工修改controller

      删除:delete请求

       出现了按钮换行 因为 form的添加 所以进行修改

       设置按钮del_uri

        button 设置 :th:attr="del_uri=@{emp/} + ${emp.id}"

        form 设置:id="deleteEmpForm"

     

      最后效果:

  • 相关阅读:
    作业作业
    Alpha 冲刺 (4/10)
    Alpha 冲刺 (3/10)
    Alpha 冲刺 (2/10)
    Alpha 冲刺 (1/10)
    项目需求分析评审表
    项目需求分析答辩总结
    项目选题报告答辩总结
    UML
    各组项目答辩评分与存在问题
  • 原文地址:https://www.cnblogs.com/lixuchun/p/8976656.html
Copyright © 2011-2022 走看看