Web 项目 tiger 之7 添加用户

需求说明

  • 在查询出所有用户的基础上,现在来添加用户操作,实现如下所示的功能

userList. html

......
<body>

<!--在原来的位置引用公共的头部元素,原来的 <nav元素就是在这里的
commonsHead:模板名,根据Spring Boot配置的Thymeleaf映射查找
head:是模板中公用的代码片段-->
<div th:replace="commons::head"></div>

<div class="container-fluid">
    <div class="row">

        <!-- 在原来的左侧菜单位置引用抽取好的公共左侧菜单代码
        1、这是使用的 id选择器 进行的引用
        2、引用公共代码的片段的同时传递参数值过去-->
        <div th:replace="commons::#commonsLeft(activeUri='userList')"></div>

        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <!-- 用户列表点击 "用户添加"按钮 后 进入后台-->
            <h2><a th:href="@{/user/userCRUD}" class="btn btn-primary">用户添加</a></h2>

            <div class="table-responsive">
                <table class="table table-striped table-sm">
                    <thead>
                    <tr>
                        <th>#</th>
                        <th>用户名</th>
                        <th>邮箱</th>
                        <th>性別</th>
                        <th>生日</th>
                        <th>所属部门</th>
                        <th>操作</th>
                    </tr>
......

domain

department

package com.lct.domain;

/**
 * 部门 实体 类
 */
public class Department {
    /**主键id*/
    private Integer depId;

    /**部门名称*/
    private String depName;

    public Department() {
    }
    public Department(int depId, String depName) {
        this.depId = depId;
        this.depName = depName;
    }

    public Integer getDepId() {
        return depId;
    }

    public void setDepId(Integer depId) {
        this.depId = depId;
    }

    public String getDepName() {
        return depName;
    }

    public void setDepName(String depName) {
        this.depName = depName;
    }

    @Override
    public String toString() {
        return "Department{" +
                "depId=" + depId +
                ", depName='" + depName + '\'' +
                '}';
    }
}

user

package com.lct.domain;

import java.util.Date;

/**
 * 用户实体类
 */
public class User {
    /**
     * 主键id
     * 用户名称
     * 电子邮箱
     */
    private Integer uId;
    private String uName;
    private String email;
    /**
     * 用户性别:1 男, 0 女
     * 生日
     */
    private Integer gender;
    private Date birth;
    /**
     * 所在的部门
     */
    private Department department;

    public Integer getUId() {
        return uId;
    }

    public void setUId(Integer uId) {
        this.uId = uId;
    }

    public String getuName() {
        return uName;
    }

    public void setuName(String uName) {
        this.uName = uName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public User(Integer uId, String uName, String email, Integer gender,
                Department department) {
        super();
        this.uId = uId;
        this.uName = uName;
        this.email = email;
        this.gender = gender;
        this.department = department;
        this.birth = new Date();
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "birth=" + birth +
                ", uId=" + uId +
                ", uName='" + uName + '\'' +
                ", email='" + email + '\'' +
                ", gender=" + gender +
                ", department=" + department +
                '}';
    }
}

dao

DepartmentDaoImpl

package com.lct.dao;

import com.lct.domain.Department;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
public class DepartmentDaoImpl {

    /**
     * 模拟数据库数据,实际不走数据库
     * 初始化数据
     */
    private static List<Department> departmentList = null;

    static {
        departmentList = new ArrayList<>();
        departmentList.add(new Department(101, "系统部"));
        departmentList.add(new Department(102, "研发部"));
        departmentList.add(new Department(103, "采购部"));
        departmentList.add(new Department(104, "财务部"));
        departmentList.add(new Department(105, "后勤部"));
    }

    /**
     * 查询部门所有数据
     *
     * @return
     */
    public List<Department> getDepartments() {
        return departmentList;
    }

    /**
     * 根据 部门id查询 部门
     *
     * @param id
     * @return
     */
    public Department getDepartmentById(Integer id) {
        if (departmentList != null && departmentList.size() > 0) {
            for (Department department : departmentList) {
                if (department.getDepId() == id) {
                    return department;
                }
            }
        }
        return null;
    }
}

UserDaoImpl

package com.lct.dao;

import com.lct.domain.Department;
import com.lct.domain.User;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Repository
public class UserDaoImpl {

    @Resource
    private DepartmentDaoImpl departmentDao;

    /**
     * 默认的用户列表数据,暂时就不通过数据库了,直接初始化一些数据进行模拟
     */
    private static List<User> userList = null;

    static {
        userList = new ArrayList<>();
        userList.add(new User(1001, "E-AA", "[email protected]", 1, new Department(101, "系统部")));
        userList.add(new User(1002, "E-BB", "[email protected]", 1, new Department(102, "系统部")));
        userList.add(new User(1003, "E-CC", "[email protected]", 0, new Department(103, "采购部")));
        userList.add(new User(1004, "E-DD", "[email protected]", 0, new Department(104, "采购部")));
        userList.add(new User(1005, "E-EE", "[email protected]", 1, new Department(105, "财务部")));
    }

    /**
     * 模拟查询所有员工
     */
    public List<User> getAll() {
        return userList;
    }

    /**
     * 添加用户
     *
     * @param user
     */
    public void saveUser(User user) {
        if (user == null) {
            return;
        }
        /**
         * 动态修改主键id
         */
        user.setUId(userList.get(userList.size() - 1).getUId() + 1);
        /**
         * 因为页面传入的 Department 只有depId,所以根据id查询它整个实体回来 
         */
        user.setDepartment(departmentDao.getDepartmentById(user.getDepartment().getDepId()));
        userList.add(user);
    }
}

UserController

package com.lct.controller;

import com.lct.dao.DepartmentDaoImpl;
import com.lct.dao.UserDaoImpl;
import com.lct.domain.Department;
import com.lct.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * Created by Administrator on 2018/7/28 0028.
 * 用户控制器层
 */
@Controller
@RequestMapping("user")
public class UserController {

    @Resource
    private UserDaoImpl userDao;

    @Resource
    private DepartmentDaoImpl departmentDao;

    /**
     * 用户登录
     *
     * @param username    账号
     * @param password    密码
     * @param httpSession 设值登录的 用户session
     * @return 登录成功 重定向到 用户列表页面
     * @PostMapping ("login") 相当于 @RequestMapping(value = "login",method = RequestMethod.POST) 的简写
     * 同理还有 @GetMapping 、@PutMapping 、@DeleteMapping
     */
    @PostMapping("login")
    public String login(String username, String password, HttpSession httpSession) {
        /**
         * 当账号不为空,密码为 123456 时,模拟登录成功,否则失败时重定向返回登录页面
         */
        if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
            httpSession.setAttribute("userName", username);
            return "redirect:/user/users";
        } else {
            /** 往服务器重定向时 要以 "/" 开头表示应用根地址*/
            return "redirect:/index";
        }
    }

    /**
     * 页面点击 "商品销量" 链接时 进入,然后跳转到 products.html 页面
     *
     * @return
     */
    @GetMapping("products")
    public String priduct() {
         /** 往前端 Thymeleaf 模板引擎时,开头不要加 "/" ,因为它默认配置就是:
         * 前缀:spring.thymeleaf.prefix=classpath:/templates/
         * 后缀:spring.thymeleaf.suffix=.html */
        return "products";
    }

    /**
     * 跳转到用户列表页面
     *
     * @param model 用户设值返回页面
     * @return
     */
    @GetMapping("users")
    public String findAllUsers(Model model) {
        List<User> userList = userDao.getAll();
        model.addAttribute("userList", userList);
        return "userList";
    }

    /**
     * 用户添加前页面跳转-----用户点击"用户添加"按钮时,今天此处进行跳转到添加页面
     *
     * @param model
     * @return
     */
    @GetMapping(value = "userCRUD")
    public String toAddUser(Model model) {
        /**
         * 因为用户添加页面上,需要选择用户属于哪个部门,所以要将部门数据全部带出去
         */
        List<Department> departmentList = departmentDao.getDepartments();
        model.addAttribute("departmentList", departmentList);
        return "userAdd";
    }

    /**
     * 用户添加-----用户添加提交时进入
     * <p/>
     * SpringMVC 自动将请求参数和入参对象的属性进行一一映射绑定
     * 要求是请求参数的名字和 User 的属性名一样
     *
     * @param user
     * @return
     */
    @PostMapping(value = "userCRUD")
    public String addUser(User user) {
        System.out.println("-----" + user);
        /**
         * 保存数据
         */
        userDao.saveUser(user);

        /** redirect: 表示重定向到一个后台地址 " /" 代表当前项目路径
         * forward: 表示转发到一个后台地址
         * 两者都是get请求方式
         */
        return "redirect:/user/users";
    }
}

addUser. html

<!DOCTYPE html>
<!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ -->
<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="">

    <title>Dashboard 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/dashboard.css" th:href="@{/asserts/css/dashboard.css}" rel="stylesheet">
    <style type="text/css">
        /* Chart.js */

        @-webkit-keyframes chartjs-render-animation {
            from {
                opacity: 0.99
            }
            to {
                opacity: 1
            }
        }

        @keyframes chartjs-render-animation {
            from {
                opacity: 0.99
            }
            to {
                opacity: 1
            }
        }

        .chartjs-render-monitor {
            -webkit-animation: chartjs-render-animation 0.001s;
            animation: chartjs-render-animation 0.001s;
        }
    </style>
</head>

<body>
<!--在原来的位置引用公共的头部元素,原来的 <nav元素就是在这里的
commonsHead:模板名,根据Spring Boot配置的Thymeleaf映射查找
head:是模板中公用的代码片段-->
<div th:replace="commons::head"></div>

<div class="container-fluid">
    <div class="row">
        <!-- 在原来的左侧菜单位置引用抽取好的公共左侧菜单代码
        1、这是使用的 id选择器 进行的引用
        2、引用公共代码的片段的同时传递参数值过去-->
        <div th:replace="commons::#commonsLeft(activeUri='userList')"></div>

        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <!--提交后进入后台地址-->
            <form method="post" th:action="@{/user/userCRUD}">
                <div class="form-group">
                    <label>姓名</label>
                    <input name="uName" type="text" class="form-control" placeholder="华安">
                </div>
                <div class="form-group">
                    <label>邮箱</label>
                    <input name="email" type="email" class="form-control" placeholder="[email protected]">
                </div>
                <div class="form-group">
                    <label>性别</label><br/>

                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" value="1">
                        <label class="form-check-label">男</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" value="0">
                        <label class="form-check-label">女</label>
                    </div>
                </div>
                <div class="form-group">
                    <label>所属部门</label>
                    <!--部门表所有部门,进行遍历显示,供用户选择
                    注意:select的 name="department.depId",Spring MVC 会自动封装关联类 Department的depId,但是depName为null-->
                    <select class="form-control" name="department.depId">
                        <option th:each="department:${departmentList}"
                                th:text="${department.depName}"
                                th:value="${department.depId}">
                        </option>
                    </select>
                </div>
                <div class="form-group">
                    <label>生日</label>
                    <input name="birth" type="text" class="form-control" placeholder="1893/08/25">
                </div>
                <button type="submit" class="btn btn-primary">添加</button>
            </form>
        </main>
    </div>
</div>

<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js"
        th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
<script type="text/javascript" src="asserts/js/popper.min.js"
        th:src="@{/webjars/popper.js/1.11.1/dist/popper.js}"></script>
<script type="text/javascript" src="asserts/js/bootstrap.min.js"
        th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.js}"></script>

<!-- Icons -->
<script type="text/javascript" src="asserts/js/feather.min.js" th:src="@{/asserts/js/feather.min.js}"></script>
<script>
    feather.replace()
</script>

</body>

</html>

运行测试

日期参数转换

背景说明

  • 页面提交的日期数据,后台 Spring MVC 进行自动转换成 Date 类型,但是默认情况下面只支持 "/"分隔的方式
addUaer.html:
<div class="form-group">
    <label>生日</label>
    <input name="birth" type="text" class="form-control" placeholder="1893/08/25">
</div>

UserController:
    /**
     * 用户添加-----用户添加提交时进入
     * <p/>
     * SpringMVC 自动将请求参数和入参对象的属性进行一一映射绑定
     * 要求是请求参数的名字和 User 的属性名一样
     *
     * @param user
     * @return
     */
    @PostMapping(value = "userCRUD")
    public String addUser(User user) {
        System.out.println("-----" + user);
        /**
         * 保存数据
         */
        userDao.saveUser(user);

        /** redirect: 表示重定向到一个后台地址 " /" 代表当前项目路径
         * forward: 表示转发到一个后台地址
         * 两者都是get请求方式
         */
        return "redirect:/user/users";
    }

# SPRING MVC (WebMvcProperties)
spring.mvc.async.request-timeout= # Amount of time before asynchronous request handling times out.
spring.mvc.contentnegotiation.favor-parameter=false # Whether a request parameter ("format" by default) should be used to determine the requested media type.
spring.mvc.contentnegotiation.favor-path-extension=false # Whether the path extension in the URL path should be used to determine the requested media type.
spring.mvc.contentnegotiation.media-types.*= # Map file extensions to media types for content negotiation. For instance, yml to text/yaml.
spring.mvc.contentnegotiation.parameter-name= # Query parameter name to use when "favor-parameter" is enabled.
spring.mvc.date-format= # Date format to use. For instance, `dd/MM/yyyy`.
spring.mvc.dispatch-trace-request=false # Whether to dispatch TRACE requests to the FrameworkServlet doService method.

解决方式

修改全局配置文件

#设置应用上下文
server.servlet.context-path=/tiger
#设置应用国际化目录
spring.messages.basename=i18n.index
#开发阶段,禁用 Thymeleaf 的缓存,即当静态资源修改之后,只需要 ctrl+F9 重新加载即可看到新内容
spring.thymeleaf.cache=false
#自定义页面日期输入的格式
spring.mvc.date-format=yyyy-MM-dd

WebDataBinder

  • 这是以前 Spring MVC 时的解决方式,自定义 日期转换器进行日期转换
package com.lct.controller;

import com.lct.dao.DepartmentDaoImpl;
import com.lct.dao.UserDaoImpl;
import com.lct.domain.Department;
import com.lct.domain.User;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2018/7/28 0028.
 * 用户控制器层
 */
@Controller
@RequestMapping("user")
public class UserController {

    @Resource
    private UserDaoImpl userDao;

    @Resource
    private DepartmentDaoImpl departmentDao;

    /**
     * 自定义日期转换器
     * Spring3.0之前是会自动转换的,但是3.0之后需要程序员自己转换
     * 直接将 @InitBinder... 此方法防止在 @Controller 中即可
     *
     * @param dataBinder
     */
    @InitBinder
    public void initBind(WebDataBinder dataBinder) {
        /**
         * new SimpleDateFormat("yyyy-MM-dd") 时:
         *  表示页面日期格式可以是:1)1993-08-25、2)1993-08-25 12:30:30(注意此时时分秒是无效的,后台会自动设置为 00:00:00)
         * new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") 时:
         *  表示示页面日期格式必须是:1)1993-08-25 12:30:30
         *  2)1993-08-25 (如果这样,则直接报错,即只能多,不能少,多了部分会清零)
         */
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        /**
         * 指定日期/时间解析是否不严格
         * lenient - 为 true 时,解析过程是不严格的
         */
        dateFormat.setLenient(true);
        /**
         * Date.class:表示这是注册的是日期类型
         * new CustomDateEditor(dateFormat, true):true 表示允许为空
         */
        dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

    /**
     * 用户登录
     *
     * @param username    账号
     * @param password    密码
     * @param httpSession 设值登录的 用户session
     * @return 登录成功 重定向到 用户列表页面
     * @PostMapping ("login") 相当于 @RequestMapping(value = "login",method = RequestMethod.POST) 的简写
     * 同理还有 @GetMapping 、@PutMapping 、@DeleteMapping
     */
    @PostMapping("login")
    public String login(String username, String password, HttpSession httpSession) {
        /**
         * 当账号不为空,密码为 123456 时,模拟登录成功,否则失败时重定向返回登录页面
         */
        if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
            httpSession.setAttribute("userName", username);
            return "redirect:/user/users";
        } else {
            return "redirect:/index";
        }
    }
.......
}
  • 此时即使全局配置文件中注释掉 #spring.mvc.date-format=yyyy-MM-dd 也是ok的了

猜你喜欢

转载自blog.csdn.net/wangmx1993328/article/details/81429287
今日推荐