视图层开发
1.简介 使用SpringBoot步骤:
1)创建SpringBoot应用,选择我们需要的模块开发
2)SpringBoot已经将这些场景配置好了。只需要在配置文件中配置少量配置就可以运行起来了
3)编写业务代码
自动配置需要理解:
这个场景SpringBoot帮我们配置了什么?能不能修改?能修改哪些配置,能不能扩展??
1 2 xxxxAutoConfiguration :帮我们给容器中自动配置组件 xxxxProperties :配置类来封装配置文件的内容
2.SpringBoot对静态资源的映射规则 1 2 @ConfigurationProperties (prefix = "spring.resources" , ignoreUnknownFields = false )public class ResourceProperties {}
1)所有/webjars/**,都去 classpath:/META-INF/resources/webjars/找资源
webjars:以jar包的方式引入静态资源 https://www.webjars.org/
localhost:8080/webjars/jquery/3.3.1-1/jquery.js
1 2 3 4 5 6 <dependency > <groupId > org.webjars</groupId > <artifactId > jquery</artifactId > <version > 3.3.1-1</version > </dependency >
2) “/**” 访问当前项目的任何资源(静态资源的文件夹)resources就是类路径下的根目录
1 2 3 4 5 6 "classpath:/META-INF/resources/" , :resources/META-INF/resources/"classpath:/resources/" , :resources/resources/"classpath:/static/" , :resources/static /"classpath:/public/" :resources/public /"/" 当前项目的根路径
localhost:8080/jquery.js == 去静态文件夹下的jquery.js
3)欢迎页,静态资源文件夹下的所有index.html;被”/**”映射
localhost:8080
4)所有的**/favicon.ico 都是在静态资源文件夹下找
依然可以在application.properties文件夹下进行自动指定
1 2 spring.resources.static-locations =classpath:/ooyhao/,
3.模板引擎 JSP、Velocity、Freemarker、Thymeleaf
SpringBoot推荐的Thymeleaf;语法更简单,功能更强大;**thymeleaf 官网 **
1、引入thymeleaf 1 2 3 4 5 6 7 8 9 10 11 12 13 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-thymeleaf</artifactId > 3.0.9 </dependency > 切换thymeleaf版本 (可以切换,但是现在已经是最新的版本了) <properties > <thymeleaf.version > 3.0.9.RELEASE</thymeleaf.version > <thymeleaf-layout-dialect.version > 2.2.2</thymeleaf-layout-dialect.version > </properties >
2、Thymeleaf使用 1 2 3 4 5 6 7 8 9 10 @ConfigurationProperties (prefix = "spring.thymeleaf" )public class ThymeleafProperties { private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8; public static final String DEFAULT_PREFIX = "classpath:/templates/" ; public static final String DEFAULT_SUFFIX = ".html" ; }
只要我们把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染;
SpringBoot 的自动配置
1 2 3 4 5 spring.thymeleaf.prefix =classpath:/templates/ spring.thymeleaf.mode =HTML spring.thymeleaf.suffix =.html spring.thymeleaf.encoding =utf-8
导入thymeleaf的名称空间,并使用thymeleaf语法;
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE html > <html lang ="en" xmlns:th ="http://www.thymeleaf.org" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 > 成功!</h1 > <div th:text ="${hello}" > 这是显示欢迎信息</div > </body > </html >
3、语法规则 1.th:text;改变当前元素里面的文本内容;
th:任意html属性;来替换原生属性的值
1 2 3 <h1 > 你好</h1 > 使用th:text 输出:<h1 > 你好</h1 > 使用th:utext输出:你好(加粗)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <table border ="1" > <tr > <td > 图书编号</td > <td > 图书名称</td > <td > 图书作者</td > <td > 图书价格</td > </tr > <tr th:each ="book : ${books}" > <td th:text ="${book.id}" > </td > <td th:text ="${book.name}" > </td > <td th:text ="${book.author}" > </td > <td th:text ="${book.price}" > </td > </tr > </table >
2.表达式?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 Simple expressions:(表达式语法) Variable Expressions: ${...}:获取变量值(OGNL); 1.获取对象的属性、调用方法 2.使用内置的基本对象:${session.foo} 3.内置的一些工具对象: Selection Variable Expressions: *{...}:选择表达式;和${}在功能上是一样; 补充:配合 th:object="${session.user} <div th:object="${session.user}"> <p>Name : <span th:text="*{firstName}">Sebastian</span></p> <p>Surname : <span th:text="*{lastName}">Pepper</span></p> <p>Nationality : <span th:text="*{nationality}">Saturn</span></p> </div> Message Expressions: #{...}:获取国际化内容 Link URL Expressions: @{...}:定义URL; @{/order/process(execId =${execId},execType='FAST')} Fragment Expressions: ~{...}:片段引用表达式 <div th:insert="~{commons :: main}">...</div> Literals(字面量) Text literals: 'one text' , 'Another one!' ,… Number literals: 0 , 34 , 3.0 , 12.3 ,… Boolean literals: true , false Null literal: null Literal tokens: one , sometext , main ,… Text operations:(文本操作) String concatenation: + Literal substitutions: |The name is ${name}| Arithmetic operations:(数学运算) Binary operators: + , - , * , / , % Minus sign (unary operator): - Boolean operations:(布尔运算) Binary operators: and , or Boolean negation (unary operator): ! , not Comparisons and equality:(比较运算) Comparators : > , < , >= , <= ( gt , lt , ge , le ) Equality operators: == , != ( eq , ne ) Conditional operators:条件运算(三元运算符) If-then : (if) ? (then) If-then-else : (if) ? (then) : (else) Default : (value) ?: (defaultvalue) Special tokens: No-Operation : _
示例 html文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <!DOCTYPE html > <html lang ="en" xmlns:th ="http://www.thymeleaf.org" > <head > <meta charset ="UTF-8" > <title > 首页</title > </head > <body > <div th:text ="${hello}" > 这是显示欢迎信息</div > <div th:utext ="${hello}" > 这是显示欢迎信息</div > <h4 th:text ="${user}" th:each ="user:${users}" > </h4 > <hr /> <h4 > <span th:each ="user:${users}" > [[${user}]]</span > </h4 > <hr /> </body > </html >
controller文件:
1 2 3 4 5 6 7 8 9 @Controller public class HelloController { @GetMapping ("/hello" ) public String hello (Map<String,Object> map) { map.put("hello" ,"<h1>你好</h1>" ); map.put("users" , Arrays.asList("张三" ,"李四" ,"王五" )); return "message" ; } }
效果图:
4、Springmvc自动配置 https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#boot-features-spring-mvc
1.Spring MVC Auto-configuration SpringBoot自动配置好了SpringMVC
以下是SpringBoot对SpringMVC的默认配置:
Spring Boot provides auto-configuration for Spring MVC that works well with mostapplications.
The auto-configuration adds the following features on top of Spring’s defaults:
Inclusion of ContentNegotiatingViewResolver
and BeanNameViewResolver
beans.
自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染,是请求转发,还是重定向)
ContentNegotiatingViewResolver:组合所有的视图解析器的
如何定制:我们可以自己给容器添加一个视图解析器;自动的将其组合进来、
Support for serving static resources, including support for WebJars (coveredlater in this document )).
Automatic registration of Converter
, GenericConverter
, and Formatter
beans.
自动注册了Converter
, GenericConverter
, and Formatter
Converter:转换器;public String hello(User user):类型转换组件
Formatter:格式化器:2017-12-17 ==> Date
自己添加格式化器,我们只需要放到容器中即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 If you need to add or customize converters, you can use Spring Boot’s HttpMessageConverters class, as shown in the following listing: import org.springframework.boot.autoconfigure.web.HttpMessageConverters;import org.springframework.context.annotation.*;import org.springframework.http.converter.*;@Configuration public class MyConfiguration { @Bean public HttpMessageConverters customConverters () { HttpMessageConverter<?> additional = ... HttpMessageConverter<?> another = ... return new HttpMessageConverters(additional, another); } }
Support for HttpMessageConverters
(coveredlater in this document ).
HttpMessageConverters:SpringMVC用来装换http请求和相应的;User–Json
HttpMessageConverters是从容器中确定的,获得所有的HttpMessageConverter;
自己给容器中添加,只需要将自己的组件注册到容器中(@Bean, @Component)
Automatic registration of MessageCodesResolver
(coveredlater in this document ). 定义错误代码生成规则。
Static index.html
support. 静态资源首页
Custom Favicon
support (covered later in thisdocument ). 图标
Automatic use of a ConfigurableWebBindingInitializer
bean (coveredlater in this document ).
我们自己可以配置一个ConfigurableWebBindingInitializer来替换默认的;(添加到容器中)
初始化web数据绑定器WebDataBinder
请求数据 == > JavaBean
org.springframework.boot.autoconfigure.web :web的所有自动配置场景。
If you want to keep Spring Boot MVC features and you want to add additionalMVC configuration (interceptors, formatters, viewcontrollers, and other features), you can add your own @Configuration
class of typeWebMvcConfigurer
but without @EnableWebMvc
. If you wish to provide custominstances of RequestMappingHandlerMapping
, RequestMappingHandlerAdapter
, orExceptionHandlerExceptionResolver
, you can declare a WebMvcRegistrationsAdapter
instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration
annotated with @EnableWebMvc
.
2.扩展SpringMVC 1 2 3 4 5 6 7 <mvc:view-controller path ="/hello" view-name ="success" /> <mvc:interceptors > <mvc:interceptor > <mvc:mapping path ="/hello" /> <bean > </bean > </mvc:interceptor > </mvc:interceptors >
编写一个配置类(@Configuration)是WebMvcConfigurer类型,不能标注@EnableWebMvc
既保留了所有的自动配置,也能用我们扩展的配置。
1 2 3 4 5 6 7 8 9 @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers (ViewControllerRegistry registry) { registry.addViewController("/ooyhao" ).setViewName("message" ); } }
原理:
1)WebMvcAutoConfiguration是springmvc的自动配置类
2)新版本使用的是WebMvcConfigurer,而不是WebMvcConfigurerAdapter,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Configuration public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration { @Configuration public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite(); @Autowired (required = false ) public void setConfigurers (List<WebMvcConfigurer> configurers) { if (!CollectionUtils.isEmpty(configurers)) { this .configurers.addWebMvcConfigurers(configurers); } } }
3)容器中所有的WebMvcConfigurer都会一起起作用
4)我们的配置类也会被调用。
效果:springmvc的自动配置和我们的扩展配置都会起作用
3.全面接管SpringMvc SpringBoot对SpringMVC的自动配置不需要了。所有的配置都是我们自己配置。所有的SpringMVC自动配置都失效了。
我们需要在配置类上添加@EnableWebMvc即可
1 2 3 4 5 6 7 8 9 10 11 12 13 @EnableWebMvc @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers (ViewControllerRegistry registry) { registry.addViewController("/ooyhao" ).setViewName("message" ); } }
原理:
1)
1 2 @Import (DelegatingWebMvcConfiguration.class ) public @interface EnableWebMvc {}
2)
1 2 @Configuration public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
3)
1 2 3 4 5 6 7 8 9 @Configuration @ConditionalOnWebApplication (type = Type.SERVLET)@ConditionalOnClass ({ Servlet.class , DispatcherServlet .class , WebMvcConfigurer .class }) //容器中没有这个组件的时候,这个自动配置类才生效 @ConditionalOnMissingBean (WebMvcConfigurationSupport .class ) @AutoConfigureOrder (Ordered .HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter ( { DispatcherServletAutoConfiguration.class , ValidationAutoConfiguration .class }) public class WebMvcAutoConfiguration {
4)@EnableWebMvc将WebMvcConfigurationSupport组件导入进来,
5)导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能
5.如何修改SpringBoot的默认配置 模式:
1)SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean,@Component)如果有就用用户配置的,如果没有,才自动配置,如果有些组件可以有多个(例如:ViewResolver)将用户配置的和默认的组合起来
2)在SpringBoot中会有非常多的*Configuration帮助我们扩展配置。
3)在springboot中也会用很多的xxxCustomizer帮助我们进行定制配置
6.RestfulCRUD 1.默认访问首页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Bean public WebMvcConfigurer webMvcConfigurer () { return new WebMvcConfigurer(){ @Override public void addViewControllers (ViewControllerRegistry registry) { registry.addViewController("/" ).setViewName("login" ); registry.addViewController("/index" ).setViewName("login" ); registry.addViewController("/index.html" ).setViewName("login" ); } }; } @RequestMapping (value = {"/" ,"/index.html" })public String index () { return "index" ; }
2.国际化 1)编写国际化配置文件
2)使用ResourceBundleMessageSource管理国际化资源文件
3)在页面使用fmt:message取出国际化内容
以前使用需要1,2,3.现在使用SpringBoot,
步骤:
1.编写国际化配置文件,抽取页面需要显示的国际化消息
2.SpringBoot自动配置好了管理国际化资源文件的组件 自动配置源码:
1 2 3 4 public class MessageSourceAutoConfiguration { private String basename = "messages" ; }
3.去页面获取国际化的值 解决中文乱码,file–>other setting–>default setting
实现了国际化效果
1 spring.messages.basename =i18n.login
html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <body class ="text-center" > <form class ="form-signin" action ="dashboard.html" > <img class ="mb-4" th:src ="@{/asserts/img/bootstrap-solid.svg}" 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" th:text ="#{login.username}" > Username</label > <input type ="text" class ="form-control" placeholder ="Username" th:placeholder ="#{login.username}" required ="" autofocus ="" > <label class ="sr-only" th:text ="#{login.password}" > 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" 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" > 中文</a > <a class ="btn btn-sm" > English</a > </form > </body >
效果:根据浏览器语言设置的信息切换国际化;
原理:国际化locale(区域信息对象);LocaleResolver(获取区域信息对象)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Bean @ConditionalOnMissingBean @ConditionalOnProperty (prefix = "spring.mvc" , name = "locale" )public LocaleResolver localeResolver () { if (this .mvcProperties .getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) { return new FixedLocaleResolver(this .mvcProperties.getLocale()); } AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); localeResolver.setDefaultLocale(this .mvcProperties.getLocale()); return localeResolver; }
4.点击链接切换国际化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class MyLocaleResolver implements LocaleResolver { @Override public Locale resolveLocale (HttpServletRequest request) { String l = request.getParameter("l" ); Locale locale = Locale.getDefault(); if (!StringUtils.isEmpty(l)){ String[] strings = l.split("_" ); locale = new Locale(strings[0 ],strings[1 ]); } return locale; } @Override public void setLocale (HttpServletRequest request, HttpServletResponse response, Locale locale) {}}
加入到SpringBoot容器中
1 2 3 4 5 @Bean public LocaleResolver localeResolver () { return new MyLocaleResolver(); }
3.登录 在开发期间,模板引擎页面修改以后, 要实时生效:
1)禁用模板引擎的缓存
1 2 spring.thymeleaf.cache =false
2)页面修改完成以后ctrl+f9,重新编译
登录错误消息显示
1 2 <p style ="color:red;" th:text ="${msg}" th:if ="${not #strings.isEmpty(msg)}" > </p >
4.拦截器进行登录检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class LoginHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException { String loginUser = (String) request.getSession().getAttribute("loginUser" ); if (loginUser != null ){ return true ; } request.setAttribute("msg" ,"没有权限,请登录" ); request.getRequestDispatcher("/index.html" ).forward(request,response); return false ; } }
如何添加拦截器:
1.编写一个自定义拦截器类并实现HandlerInterceptor接口;编写相应的逻辑
2.在webmvc配置类中配置配置注册拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 @Configuration public class MyMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers (ViewControllerRegistry registry) { registry.addViewController("/ooyhao" ).setViewName("message" ); } @Bean public WebMvcConfigurer webMvcConfigurer () { return new WebMvcConfigurer(){ @Override public void addViewControllers (ViewControllerRegistry registry) { registry.addViewController("/" ).setViewName("login" ); registry.addViewController("/index" ).setViewName("login" ); registry.addViewController("/index.html" ).setViewName("login" ); registry.addViewController("/main.html" ).setViewName("dashboard" ); } @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()) .addPathPatterns("/**" ) .excludePathPatterns("/index.html" ,"/" ,"index" ,"/user/login" ,"/webjars/**" ,"/asserts/**" ) ; } }; } @Bean public LocaleResolver localeResolver () { return new MyLocaleResolver(); } }
5.CRUD员工列表 1.RestfulCRUD URI:/资源名称/资源标识 HTTP请求方式区分对资源CRUD操作
普通CRUD
RestfulCRUD
查询
getEmp
emp–GET
添加
addEmp?xxx
emp–POST
修改
update?id=xxx&xxx=xxx
emp/{id}–PUT
删除
deleteEmp?id=1
emp/{id}–DELETE
2.实验的请求架构
请求的URI
请求方式
查询所有员工
emps
GET
查询某个员工
emp/1
GET
来到添加页面
emp
GET
添加员工
emp
POST
来到修改页面(查询员工信息回显)
emp/1
GET
修改员工
emp
PUT
删除员工
emp/1
DELETE
3.员工列表 1.thymeleaf公共页面元素抽取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1.抽取公共片段,利用th:fragment <div th:fragment ="copy" > © 2011 The Good Thymes Virtual Grocery </div > 2.引入公共片段 <div th:insert ="~{footer :: copy}" > </div > ~{templatename::selector}:模板名::选择器 <div th:replace ="~{dashboard::topbar}" > </div > ~{templatename::fragmentname}:模板名::片段名 <div th:replace ="~{dashboard::#sidebar}" > </div > 3.默认效果 insert的动能片段在div标签中 如果使用th:insert等属性进行引入,可以不用写~{}: 行内写法可以加上:[[~{}]],[(~{})]
三种引入功能片段的th属性:
1.th:insert:将公共片段整个插入到整个声明引入的元素中
2.replace:将声明引入的元素替换成公共片段
3.include:被引入的片段的内容包含进这个标签中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <footer th:fragment ="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 > <div > <footer > © 2011 The Good Thymes Virtual Grocery </footer > </div > <footer > © 2011 The Good Thymes Virtual Grocery </footer > <div > © 2011 The Good Thymes Virtual Grocery </div >
再引入片段的时候传入参数:
在抽取的部分进行定义判断 th:class=”${activeUri == ‘emps’?’nav-link active’:’nav-link’}”
1 2 3 4 5 6 7 8 9 10 11 <a class ="nav-link active" href ="#" th:class ="${activeUri == 'emps'?'nav-link active':'nav-link'}" 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 >
在引入的地方进行变量赋值
1 <div th:replace ="~{commons/bar::#sidebar(activeUri='emps')}" > </div >
2.添加页面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <form > <div class ="form-group" > <label > LastName</label > <input type ="text" class ="form-control" placeholder ="zhangsan" > </div > <div class ="form-group" > <label > Email</label > <input type ="email" class ="form-control" placeholder ="zhangsan@atguigu.com" > </div > <div class ="form-group" > <label > Gender</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 > department</label > <select class ="form-control" > <option > 1</option > <option > 2</option > <option > 3</option > <option > 4</option > <option > 5</option > </select > </div > <div class ="form-group" > <label > Birth</label > <input type ="text" class ="form-control" placeholder ="zhangsan" > </div > <button type ="submit" class ="btn btn-primary" > 添加</button > </form >
员工添加提交的数据格式不对:生日—日期
2017-12-12;2017/12/12;2017.12.12
日期的格式化:SpringMVC将页面提交的值需要转换为指定的类型
默认日期是按照斜线/方式;在配置文件中自定义时间格式:
1 2 spring.mvc.date-format =yyyy-MM-dd
3.更新与修改的页面复用,以及如何提交PUT请求 请求除get,post请求之外的请求,使用一个隐藏域,name=”_method”.value=”put”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <form th:action ="@{/emp}" th:method ="post" method ="post" > <input type ="hidden" name ="_mathod" value ="put" th:if ="${emp!=null}" > <input type ="hidden" name ="id" th:value ="${emp!= null}?${emp.id}" > <div class ="form-group" > <label > LastName</label > <input name ="lastName" type ="text" class ="form-control" placeholder ="zhangsan" th:value ="${emp!=null}?${emp.lastName}" > </div > <div class ="form-group" > <label > Email</label > <input name ="email" type ="email" class ="form-control" placeholder ="zhangsan@atguigu.com" th:value ="${emp!=null}?${emp.email}" > </div > <div class ="form-group" > <label > Gender</label > <br /> <div class ="form-check form-check-inline" > <input class ="form-check-input" type ="radio" name ="gender" value ="1" th:checked ="${emp!=null}?${emp.gender == 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" th:checked ="${emp!=null}?${emp.gender == 0} " > <label class ="form-check-label" > 女</label > </div > </div > <div class ="form-group" > <label > department</label > <select class ="form-control" name ="department.id" > <option th:each ="dept:${depts}" th:text ="${dept.departmentName}" th:value ="${dept.id}" th:selected ="${emp!=null}?${emp.department.id} == ${dept.id}" > </option > </select > </div > <div class ="form-group" > <label > Birth</label > <input type ="text" class ="form-control" name ="birth" placeholder ="zhangsan" th:value ="${emp!=null}?${#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')}" > </div > <button type ="submit" class ="btn btn-primary" th:text ="${emp!=null}?'修改':'添加'" > 添加</button > </form >