SpringBoot(五)——Web开发实验

本文详述SpringBoot框架下实现RESTful风格的增删改查操作,涵盖国际化配置、登录验证、拦截器应用及员工信息管理的全流程示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 导入静态资源文件

  • 将静态资源(css,img,js)添加到项目中,放到springboot默认的静态资源文件夹下
  • 将模板文件(html)放到template文件夹下
    在这里插入图片描述

1.1 默认访问首页

template文件夹不是静态资源文件夹,默认是无法直接访问的,所以要添加视图映射,可以在MVC配置中写,也可以再controller中写。

//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能 ,实现WebMvcConfigurer接口
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }
}

2. i18n国际化

  1. 编写国际化配置文件,抽取页面需要显示的国际化消息
    创建i18n文件夹存放配置文件,文件名格式为基础名(login)+语言代码(zh)+国家代码(CN)
    在这里插入图片描述
  2. SpringBoot 自动配置好了管理国际化资源文件的组件,MessageSourceAutoConfiguration
@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnMissingBean(
    name = {"messageSource"},
    search = SearchStrategy.CURRENT
)
@AutoConfigureOrder(-2147483648)
@Conditional({MessageSourceAutoConfiguration.ResourceBundleCondition.class})
@EnableConfigurationProperties
public class MessageSourceAutoConfiguration {
    private static final Resource[] NO_RESOURCES = new Resource[0];

    public MessageSourceAutoConfiguration() {
    }

    @Bean
    @ConfigurationProperties(
        prefix = "spring.messages"
    )
    public MessageSourceProperties messageSourceProperties() {
        return new MessageSourceProperties();
    }

    @Bean
    public MessageSource messageSource(MessageSourceProperties properties) {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        //basename为messages,我们的国际化配置文件可以放在类路径下交messages.properties中,这样可以直接使用
        //如果不使用messages.properties,需要自己指定国际化配置文件
        if (StringUtils.hasText(properties.getBasename())) {
         //设置国际化资源文件的基础名(去掉语言国家代码的)    messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
        }

        if (properties.getEncoding() != null) {
            messageSource.setDefaultEncoding(properties.getEncoding().name());
        }

        messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
        Duration cacheDuration = properties.getCacheDuration();
        if (cacheDuration != null) {
            messageSource.setCacheMillis(cacheDuration.toMillis());
        }

        messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
        messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
        return messageSource;
    }
....

在配置文件中添加国际化文件的位置和基础名

spring.messages.basename=i18n.login

如果配置文件中没有配置基础名,就在类路径下找基础名为message的配置文件

  1. 将页面文字改为获取国际化配置,格式#{key}
<body class="text-center">
	<form class="form-signin" action="dashboard.html">
		<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>
		<label class="sr-only">Username</label>
		<input type="text" class="form-control" th:placeholder="#{login.username}" placeholder="Username" required="" autofocus="">
		<label class="sr-only">Password</label>
		<input type="password" class="form-control" th:placeholder="#{login.password}" 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" th:text="#{login.btn}" type="submit">Sign in</button>
		<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
		<a class="btn btn-sm">中文</a>
		<a class="btn btn-sm">English</a>
	</form>

</body>
  1. 更改浏览器语言,页面就会使用对应的国际化配置文件
    在这里插入图片描述

2.1 原理

国际化Locale(区域信息对象),LocaleResolver(获取区域信息对象的组件);

在springmvc配置类WebMvcAutoConfiguration中注册了该组件

@Bean
/**
  *前提是容器中不存在这个组件,
 *所以使用自己的对象就要配置@Bean让这个条件不成立(实现LocaleResolver 即可)
 */
@ConditionalOnMissingBean

/**
  * 如果在application.properties中有配置国际化就用配置文件的
  * 没有配置就用AcceptHeaderLocaleResolver 默认request中获取
  */
@ConditionalOnProperty(
    prefix = "spring.mvc",
    name = {"locale"}
)
public LocaleResolver localeResolver() {
    if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
        return new FixedLocaleResolver(this.mvcProperties.getLocale());
    } else {
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
        return localeResolver;
    }
}

默认的就是根据请求头带来的区域信息获取Locale进行国际化

 public Locale resolveLocale(HttpServletRequest request) {
        Locale defaultLocale = this.getDefaultLocale();
        if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
            return defaultLocale;
        } else {
            Locale requestLocale = request.getLocale();
            List<Locale> supportedLocales = this.getSupportedLocales();
            if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
                Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
                if (supportedLocale != null) {
                    return supportedLocale;
                } else {
                    return defaultLocale != null ? defaultLocale : requestLocale;
                }
            } else {
                return requestLocale;
            }
        }
    }

2.2 点击连接切换语言

实现点击连接切换语言,而不是更改浏览器

  1. 自己实现区域信息解析器
public class MyLocaleResolver implements LocaleResolver {

    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //获取请求参数中的语言
        String language = httpServletRequest.getParameter("l");
        //没带区域信息参数就用系统默认的
        Locale locale = Locale.getDefault();
        if (!StringUtils.isEmpty(language)) {
            //提交的参数是zh_CN (语言代码_国家代码)
            String[] s = language.split("_");

            locale = new Locale(s[0], s[1]);

        }

        return locale;
    }

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

    }
}
  1. 在配置类中将其注册到容器中
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index").setViewName("login");
        registry.addViewController("/index.html").setViewName("login");
    }

    @Bean
    public LocaleResolver localeResolver() {
        return new MyLocaleResolver();
    }

}
  1. 修改页面,点击连接携带语言参数
<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>

3. 登录

  1. 编写Controller页面
@Controller
public class LoginController {
    //@RequestMapping(value = "/login", method = RequestMethod.POST)
    @PostMapping("/login")//使用这个注解,请求方式直接是post方式
    public String login(String userName, String password, Map<String, Object> map){
        if(!StringUtils.isEmpty(userName) && "123456".equals(password)){
            //登录成功,重定向到dashboard页面,防止表单重复提交
            return "redirect:/main.html";
        }else{
            //登录失败
            map.put("msg", "用户名或密码错误");
            return "login";
        }
    }
}
  1. 修改表单提交地址,输入框添加name值与参数名称对应
	<form class="form-signin" method="post" action="/login">
			<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 class="sr-only">Username</label>
			<input type="text" name="userName" class="form-control" th:placeholder="#{login.username}" placeholder="Username" required="" autofocus="">
			<label class="sr-only">Password</label>
			<input type="password" name="password" class="form-control" th:placeholder="#{login.password}" placeholder="Password" required="">
			<div class="checkbox mb-3">
				<label>
          <input type="checkbox" value="remember-me"> [[#{login.remember}]]
  1. 添加登录失败信息
<!--先判断msg是否为空,如果为空,就不显示文本-->
<p style="color: red" th:text="${msg}" th:if="${ not #strings.isEmpty('msg')}"></p>

3.1 修改页面立即生效

在配置文件中添加spring.thymeleaf.cache=false,禁止使用模板引擎的缓存

在页面修改完以后,使用ctrl + F9,重新编译

3.2 编写拦截器进行登录检查

  1. 编写拦截器类,实现HandlerInterecptor接口,重写preHandle方法
public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override //目标方法执行之前
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Object user = session.getAttribute("userName");
        if(user == null){
            //未登录,返回登录页面
            request.setAttribute("msg", "没有权限,请登录");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        }
        //已登录,放行请求
        return true;

    }
}
  1. 注册拦截器
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能 ,实现WebMvcConfigurer接口
@Configuration
//@EnableWebMvc //使SpringMVC的自动配置失效
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //收到hi请求,返回t页面,也就是将t.html交给模板引擎渲染
       // registry.addViewController("/hi").setViewName("t");
        //添加映射器
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index").setViewName("login");
        registry.addViewController("/index.html").setViewName("login");
        registry.addViewController("/main.html").setViewName("dashboard");
    }

    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }

    //定义不拦截路径
    String[] excludedPath = {"/", "/index", "/index.html", "/asserts/**","/webjars/**"};
    @Override //注册拦截器
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截所有请求,并且排除一些不需要拦截的请求和静态资源请求
        registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns(excludedPath);
    }
}

在spring2.0+的版本中,只要用户自定义了拦截器,则静态资源会被拦截。但是在spring1.0+的版本中,是不会拦截静态资源的。

因此,在使用spring2.0+时,配置拦截器之后,我们要把静态资源的路径加入到不拦截的路径之中。

4. CRUD-员工列表

CRUD 满足Rest风格

Rest 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。

Rest 风格特点

  • 每一个URI代表1种资源;
  • 客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
普通CRUD(uri来区分操作)RestfulCRUD
查询getEmpemp—GET
添加addEmp?xxxemp—POST
修改updateEmp?id=xxx&xxx=xxemp/{id}—PUT
删除deleteEmp?id=1emp/{id}—DELETE

4.1 实验的请求架构

实验功能请求URI请求方式
查询所有员工empsGET
查询某个员工(来到修改页面)emp/1GET
来到添加页面empGET
添加员工empPOST
来到修改页面(查出员工进行信息回显)emp/1GET
修改员工empPUT
删除员工emp/1DELETE

4.2 查询所有员工

  1. 编写controller 层
@Controller
public class EmployeeController {
    @Autowired
    public EmployeeDao employeeDao;

    @GetMapping("/emps")
    //查询所有员工,返回list页面
    public String findAll(Model model){
        Collection<Employee> employees = employeeDao.getAll();
        model.addAttribute("emps", employees);
        //thmeleaf默认会进行拼串,classpath://templates/emp/list.html
        return "emp/list";
    }
}

  1. 编写dao层,这里省略Service 层的编写,并且使用静态数据
@Repository
public class EmployeeDao {

	private static Map<Integer, Employee> employees = null;
	
	@Autowired
	private DepartmentDao departmentDao;
	
	static{
		employees = new HashMap<Integer, Employee>();

		employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1, new Department(101, "D-AA")));
		employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1, new Department(102, "D-BB")));
		employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0, new Department(103, "D-CC")));
		employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0, new Department(104, "D-DD")));
		employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1, new Department(105, "D-EE")));
	}
	
	private static Integer initId = 1006;
	
	public void save(Employee employee){
		if(employee.getId() == null){
			employee.setId(initId++);
		}
		
		employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));
		employees.put(employee.getId(), employee);
	}

	//查询所有员工
	public Collection<Employee> getAll(){
		return employees.values();
	}
	
	public Employee get(Integer id){
		return employees.get(id);
	}
	
	public void delete(Integer id){
		employees.remove(id);
	}
}

  1. 修改页面
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#" th:href="@{/emps}">
	用户管理
</a>
</li>

emp/list页面的左边侧边栏是和后台页面一模一样的,每个都要修改很麻烦,接下来,抽取公共片段

4.3 thymeleaf公共页面元素抽取

抽取公共片段

 <div th:fragment="copy"> 
	&copy; 2011 The Good Thymes Virtual Grocery 
</div>   

引入公共片段

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

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

在这里插入图片描述

在这里插入图片描述
默认效果

insert的公共片段在div标签中

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

  • th:insert :将公共片段整个插入到声明引入的元素中
  • th:replace:将声明引入的元素替换为公共片段
  • th:include:将被引入的片段内容包含进这个标签
<footer th:fragment="copy">
  &copy; 2011 The Good Thymes Virtual Grocery
</footer>

使用三种方式引入公共片段

<body>

  ...

  <div th:insert="footer :: copy"></div>

  <div th:replace="footer :: copy"></div>

  <div th:include="footer :: copy"></div>
  
</body>

结果如下

<body>
  ...

  <div>
    <footer>
      &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
  </div>

  <footer>
    &copy; 2011 The Good Thymes Virtual Grocery
  </footer>

  <div>
    &copy; 2011 The Good Thymes Virtual Grocery
  </div>
  
</body>

当使用这三个属性来引入公共片段时,可以省略~{},不使用这三个属性的话,可以使用行内写法[[~{...}] 或者 [(~{...})]

另外,声明公共片段时,可以只给公共片段指定一个id,使用时用~{模板名::#id}

//声明公共片段
<nav class="col-md-2 d-none d-md-block bg-light sidebar" id="leftbar">

使用公共片段

<div class="row" th:insert="dashboard::#leftbar">

具体说明可以参考官方文档

4.4 引入片段传递参数

实现点当前项高亮

将dashboard.html中的公共代码块抽出为单独的html文件,放到commos文件夹下

在引入代码片段的时候可以传递参数,然后在sidebar代码片段模板中判断当前点击的链接

语法:

~{templatename::selector(变量名=)}

/*或者在定义代码片段时,定义参数*/
<nav th:fragment="topbar(A,B)"
/*引入时直接传递参数*/
~{templatename::fragmentname(A值,B值)}

在这里插入图片描述

在这里插入图片描述

显示员工数据,添加增删改按钮

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
	<h2><button class="btn btn-sm btn-success">添加</button></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>
				</tr>
			</thead>
			<tbody>
				<!--emp代表epms中的单个对象-->
				<tr th:each="emp:${emps}">
					<td th:text="${emp.id}"></td>
					<td th:text="${emp.lastName}"></td>
					<td th:text="${emp.email}"></td>
					<td th:text="${emp.gender} == 1 ? '男' : '女'" ></td>
					<!--使用thymeleaf中的内置对象修改日期格式-->
					<td th:text="${#dates.format(emp.birth, 'yyyy-MM-dd')}"></td>
					<td>
						<button class="btn btn-sm btn-primary">编辑</button>
						<button class="btn btn-sm btn-danger">删除</button>
					</td>
				</tr>
			</tbody>
		</table>
	</div>
</main>

4.5 员工添加

1 创建添加页面add.html,表单使用的是BootStrap提供的模板,可以去BootStrap官网找。

<body>
<!--模板名会使用thymeleaf的前后缀配置规则-->
<div th:replace="~{common/bar::topbar}"></div>
<div class="container-fluid">
    <div class="row" >
        <!--引入左边栏-->
        <div th:replace="common/bar::#leftbar(activeUri='emps')"></div>

        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <form>
                <div class="form-group">
                    <label for="exampleFormControlInput1">员工姓名</label>
                    <input type="text" name="lastName" class="form-control" id="exampleFormControlInput1" placeholder="员工姓名">
                </div>
                <div class="form-group">
                    <label for="exampleFormControlInput1">邮箱</label>
                    <input type="email" name="email" class="form-control"  placeholder="邮箱">
                </div>
                <div class="form-group">
                    <label for="exampleFormControlInput1">性别</label><br>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" id="inlineRadio1" value="1">
                        <label class="form-check-label" for="inlineRadio1"></label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="gender" id="inlineRadio2" value="0">
                        <label class="form-check-label" for="inlineRadio2"></label>
                    </div>
                </div>

                <div class="form-group">
                    <label for="exampleFormControlSelect1">部门</label>
                    <select class="form-control" id="exampleFormControlSelect1">
                        <!--提交的是部门id-->
                        <option th:value="${d.id}" th:each="d:${deparments}" th:text="${d.departmentName}"></option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="exampleFormControlInput1">出生日期</label>
                    <input type="text" name="birth" class="form-control"  placeholder="出生日期">
                </div>
                <button type="submit" class="btn btn-success" >添加</button>
            </form>
        </main>
    </div>
</div>

2 点击链接跳转到添加页面

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

3 添加映射方法

 //到添加页面
    @GetMapping("/toAddPage")
    public String toAddPage(Model model){
        //获取部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("deparments", departments);
        return "/emp/add";
    }

4 修改页面遍历添加下拉选项

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

5 表单提交,添加员工

<form th:action="@{/emp}" method="post">
//添加员工
@PostMapping("/emp")
 public String add(Employee employee) {
     System.out.println(employee);
     employeeDao.save(employee);
     //redirect: 表示重定向  forward:请求转发
     //重定向到员工列表
     return "redirect:/emps";
 }

4.6 日期格式修改

表单提交的日期格式必须是yyyy/MM/dd的格式,可以在配置文件中修改格式

#指定日期格式
spring.mvc.format.date=yyyy-MM-dd

4.7 员工修改

1 点击按钮跳转到编辑页面

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

2 到员工修改页面

//到修改员工页面
 @GetMapping("/emp/{id}") //使用@PathVariable注解获取url中的id值,赋给参数id
  public String toUpdate(@PathVariable("id") Integer id, Model model) {
      Employee employee = employeeDao.get(id);
      model.addAttribute("emp", employee);
      //获取部门信息
      Collection<Department> departments = departmentDao.getDepartments();
      model.addAttribute("deparments", departments);
      return "/emp/edit";
  }

@PathVariable 和 @RequestParam的区别

@PathVariable是获取url上的数据,@RequestParam是获取请求参数的(包括post表单提交)

3 信息回显以及修改提交方式为put

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
   
     <form th:action="@{/emp}" method="post">
     	<!-- 员工id-->
         <input type="hidden" name="id" th:value="${emp.id}">
         
         <!--发送put请求,修改员工数据,表单页面只支持get/post方式,不能直接修改method=put
         1. SpringMvc配置HiddenHttpMethodFilter (SpringBoot自动配置好的)
         2. 创建一个post表单
         3. 创建一个input项,name="_method",值就是我们指定的请求方式
     	-->
         <input type="hidden" name="_method" value="put">
         <div class="form-group">
             <label for="exampleFormControlInput1">员工姓名</label>
             <input type="text" name="lastName" class="form-control" id="exampleFormControlInput1" placeholder="员工姓名" th:value="${emp.lastName}">
         </div>
         <div class="form-group">
             <label for="exampleFormControlInput1">邮箱</label>
             <input type="email" name="email" class="form-control"  placeholder="邮箱" th:value="${emp.email}">
         </div>
         <div class="form-group">
             <label for="exampleFormControlInput1">性别</label><br>
             <div class="form-check form-check-inline">
                 <input class="form-check-input" type="radio" name="gender" id="inlineRadio1" th:checked="${emp.gender==1}">
                 <label class="form-check-label" for="inlineRadio1"></label>
             </div>
             <div class="form-check form-check-inline">
                 <input class="form-check-input" type="radio" name="gender" id="inlineRadio2" value="0" th:checked="${emp.gender==0}">
                 <label class="form-check-label" for="inlineRadio2"></label>
             </div>
         </div>

         <div class="form-group">
             <label for="exampleFormControlSelect1">部门</label>
             <select name="department.id" class="form-control" id="exampleFormControlSelect1">
                 <!--提交的是部门id-->
                 <option th:value="${d.id}" th:each="d:${deparments}" th:text="${d.departmentName}" th:selected="${d.id} == ${emp.department.id}"></option>
             </select>
         </div>
         <div class="form-group">
             <label for="exampleFormControlInput1">出生日期</label>
             <input type="text" name="birth" class="form-control"  placeholder="出生日期" th:value="${#dates.format(emp.birth, 'yyyy-MM-dd')}">
         </div>
         <button type="submit" class="btn btn-success" >修改</button>
     </form>
 </main>

4 手动配置HiddenMethodFilter

spring.mvc.hiddenmethod.filter.enabled=true

5 修改员工信息

//修改员工信息
    @PutMapping("/emp")
    public String update(Employee employee) {
        System.out.println(employee);
        employeeDao.save(employee);
        return "redirect:/emps";
    }

4.8 删除员工

1 修改删除按钮

<!--使用th:attr自定义属性-->
<button th:attr="del_uri=@{/emp/} + ${emp.id}" class="btn btn-sm btn-danger deleteBtn">删除</button>
									

2 在外部写一个form表单,并将提交方式改为delete

<form id="deleteEmpForm" method="post">
	<input type="hidden" name="_method" value="delete">
</form>

3 使用js,每次点击删除按钮,就提交一次表单

<script type="text/javascript">
	$(".deleteBtn").click(function(){
		//获取删除按钮中自定义的deleteUri标签,$(this).attr(del_uri)
		// 把表单的action改为del_uri,并提交
		$("#deleteEmpForm").attr("action", $(this).attr("del_uri")).submit();
		return false;
	})

</script>

参考:SpringBoot 权威教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值