Web开发

Web开发

七月 18, 2019

Web开发

使用SpringBoot:

  1. 创建SpringBoot应用,选择我们需要的模块
  2. SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来
  3. 自己编写业务代码

自动配置原理

这个场景SpringBoot帮我们配置了什么?能不能修改?能修改哪些配置?能不能扩展?

xxxAutoConfiguration就是容器中自动配置的组件

xxxProperties配置类来封装配置文件的内容

静态资源的映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{ "classpath:/METAINF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}

String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}

}
}
  1. ==所以/Webjars/**都去classpath:/META-INF/resoures/webJars/找资源;webjars:以jar包的方式引入静态资源;==

参考:https://www.webjars.org/

pom文件中引入

1
2
3
4
5
6
<!--引入jquery-webjar模块-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>

测试:http://localhost:8080/webjars/jquery/3.3.1/jquery.js

  1. ==“/**”访问当前项目的任何资源(静态资源的文件夹)==
1
2
3
4
5
"classpath:/META-INF/resources/", 
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/",
"/"当前项目的根路径

测试:http://localhost:8080/assets/css/bootstrap.css

  1. ==欢迎页映射,静态资源文件夹下的所有index.html页;被“/**”映射==
1
2
3
4
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
}
  1. ==配置喜欢的图标,所有的**/favicon.ico都是在静态资源文件下找==
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
@ConditionalOnProperty(
value = {"spring.mvc.favicon.enabled"},
matchIfMissing = true
)
public static class FaviconConfiguration implements ResourceLoaderAware {
private final ResourceProperties resourceProperties;
private ResourceLoader resourceLoader;

public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
}

public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}

@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(-2147483647);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", this.faviconRequestHandler()));
return mapping;
}

@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler.setLocations(this.resolveFaviconLocations());
return requestHandler;
}

private List<Resource> resolveFaviconLocations() {
String[] staticLocations = WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.getResourceLocations(this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList(staticLocations.length + 1);
Stream var10000 = Arrays.stream(staticLocations);
ResourceLoader var10001 = this.resourceLoader;
this.resourceLoader.getClass();
var10000.map(var10001::getResource).forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}
}

注意:若想使用自己配的路径只需要在application.properties中配置相应路径即可,如下所示,多个路径用,隔开

强调:在使用您配置的路径后,默认配置的则不生效了。

1
spring.resources.static-locations=classpath:/hello/,classpath/test/

模板引擎

jsp,Velocity,Freemarker,Thymeleaf;这些都是模板引擎

SpringBoot推荐的Thymeleaf

引入Thymenleaf

1
2
3
4
5
<!--引入模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

切换版本

1
2
3
4
5
6
7
<properties>
<java.version>1.8</java.version>
<!--thymeleaf3版本-->
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<!--布局功能的支持程序,thymeleaf3主程序需要layout2以上版本-->
<thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
</properties>

Thymeleaf使用&语法

1
2
3
4
5
6
7
8
9
10
11
12
13
@ConfigurationProperties(
prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
private boolean checkTemplate = true;
private boolean checkTemplateLocation = true;
private String prefix = "classpath:/templates/";
private String suffix = ".html";
private String mode = "HTML";
//只要我们把HTML页面放到classpath:/templates/下,就能自动渲染
  1. 导入thymeleaf的命名空间
1
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  1. 使用thymeleaf语法
1
<div th:text="${hello1}"></div>

语法规则

  1. th:text;改变当前元素里面的文本内容
Feature Attributes jsp(说明)
Fragment inclusion th:insert,th:replace jsp:include
Fragment iteration th:each c:forEach
Conditional evaluation th:if; th:unless; th:switch; th:case c:if
Local variable definition th:object,th:with c:set
General attribute modification th:attr,th:attrprepend,th:attrappend 任意属性修改,支持prepend,append
Specific attribute modification th:value,th:href,th:src 修改指定属性默认的值
Text (tag body modification) th:text(转义特殊字符),th:utext(不转义特殊字符) 修改标签体内容
Fragment specification th:fragment 声明片段
Fragment removal th:remove 移除片段
  1. 表达式
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
Simple expressions:
Variable Expressions: ${...}:获取变量值
Selection Variable Expressions: *{...}
Message Expressions: #{...}
Link URL Expressions: @{...}
Fragment Expressions: ~{...}
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: _

SpringMvc

参考链接:https://docs.spring.io/spring-boot/docs/1.5.0.RELEASE/reference/htmlsingle/#boot-features-spring-mvc

Spring MVC auto-configuration

SpringBoot自动配好了SpringMvc

以下是SpringBoot对SpringMvc的默认

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    • 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象View,视图对象决定如何渲染,是转发页面还是重定向……)
    • ContentNegotiatingViewResolver:组合所有的视图解析器;
    • ==如何定制,可以给容器中添加视图解析器,自动将其组合==
  • Support for serving static resources, including support for WebJars (see below).静态资源文件夹路径webjars

  • Automatic registration of Converter, GenericConverter, Formatter beans.
    • Converter:转换器;
    • Formatter:格式化器;
    • 自己添加的格式化转化器只要放在容器中即可
  • Support for HttpMessageConverters (see below).
    • HttpMessageConverters:SpringMvc用来转换http请求和响应的User—json;
  • Automatic registration of MessageCodesResolver (see below).
  • Static index.html support. 静态首页访问
  • Custom Favicon support (see below). favicon.ico
  • Automatic use of a ConfigurableWebBindingInitializer bean (see below).

If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

扩展SpringMvc

1
2
3
4
5
6
7
8
<!--原始SpringMVC拦截器-->
<mvc:view-controller path="/hello" view-name="success"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>

==编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型,但是不能标注@EnableWebMvc==

1
2
3
4
5
6
7
8
9
10
//扩展Mvc,保留了Spring
@Configuration
public class MyMvcConfig extends WebMvcConfigurationSupport{
@Override
public void addViewControllers(ViewControllerRegistry registry) {

//浏览器发送/haha请求,来到success页面
registry.addViewController("/hahaha").setViewName("success");
}
}

常用的接口:

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
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;
/** 添加拦截器 **/
void addInterceptors(InterceptorRegistry registry);
/** 这里配置视图解析器 **/
void configureViewResolvers(ViewResolverRegistry registry);
/** 配置内容裁决的一些选项 **/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 视图跳转控制器 **/
void addViewControllers(ViewControllerRegistry registry);
/** 静态资源处理 **/
void addResourceHandlers(ResourceHandlerRegistry registry);
/** 默认静态资源处理器 **/
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;
/** 添加拦截器 **/
void addInterceptors(InterceptorRegistry registry);
/** 这里配置视图解析器 **/
void configureViewResolvers(ViewResolverRegistry registry);
/** 配置内容裁决的一些选项 **/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 视图跳转控制器 **/
void addViewControllers(ViewControllerRegistry registry);
/** 静态资源处理 **/
void addResourceHandlers(ResourceHandlerRegistry registry);
/** 默认静态资源处理器 **/
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);

注意!!!!!!!!!!!!!!!

配置有两种方法,一是继承继承WebMvcConfigurationSupport: (==但是会是SpringBoot的默认配置失效,无法访问默认静态资源==)重写addResourceHandlers方法,解决如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {

@Override
public void addViewControllers(ViewControllerRegistry registry) {

//浏览器发送/haha请求,来到success页面
registry.addViewController("/hahaha").setViewName("success");
}

//拦截静态资源
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry);
}

}

二是实现WebMvcConfigurer接口,然后重写addViewControllers,==该方式不会使SpringBoot默认静态资源路径失效==: 如下

1
2
3
4
5
6
7
8
9
10
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送/haha请求,来到success页面
registry.addViewController("/hahaha").setViewName("success");
}

}

如何修改默认配置

SpringBoot自动配置很多组件时,先看容器中有没有用户自己配置的(@Bean,@Component),如果有就用用户配置的,若没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来。

RestfulCRUD

####默认访问首页

  1. 在单独的config文件夹下,配置相关拦截,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.springbootweb.config;


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送/haha请求,来到success页面
registry.addViewController("/").setViewName("login");
registry.addViewController("/login").setViewName("login");
}
}
  1. 修改页面的静态资源路径,将公共资源提取出来,统一在pom文件中配置

    在pom文件中引入公共资源bootstrap代码如下:

    1
    2
    3
    4
    5
    6
    <!--引入bootstrap-->
    <dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>4.3.1</version>
    </dependency>

    将页面的相关静态资源修改,例如:

    1
    <link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.3.1/css/bootstrap.css}" rel="stylesheet">

    若是非webjars引入的资源,直接将路径修改成如下:

1
<img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72">

国际化

  1. 编写国际化配置文件

    编写国际化文件,抽取页面需要显示的国际化消息

    在Resources文件夹下创建一个i18n文件夹,再里面创建login.properties文件(默认显示),创建login_en_US.properties文件(英文显示),创建login_zh_CN.properties文件(中文显示),点开其中一个,在代码编写框的左下角点开ResourceBundle视图如图所所示:

    eFyTRx.png

  1. 使用ResourceBundleMessageSource管理国际化资源文件

    SpringBoot自动配置好了管理国际化资源的文件的组件

    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
    @Bean
    @ConfigurationProperties(
    prefix = "spring.messages"//配置文件可以放在类路径下叫messages.properties
    )
    public MessageSourceProperties messageSourceProperties() {
    return new MessageSourceProperties();
    }

    @Bean
    public MessageSource messageSource(MessageSourceProperties properties) {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    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;
    }

    在application.properies文件中配置如下代码

    1
    spring.messages.basename=i18n.login
  2. 在页面中使用fmt:message取出国际化内容

    若是在标签内部则用th:”#{…}”

    若是在placeholder中,则用th:placeholder=”#{…}”

    若是不在标签内部,则用行内表达式[[#{…}]]

    注:页面中文会出现乱码,需要在setting中设置properties文件的编码格式

    eFIJKA.png

    效果:能根据浏览器语言设置切换

    1. 按钮切换中英文

设置按钮的传入值,将不同语言的头部传入,供浏览器解析,如下所示:

1
2
<a class="btn btn-sm" th:href="@{/login(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/login(l='en_US')}">English</a>

创建一个Controller类,用来解析传入值,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MyLocaleResolver implements LocaleResolver{

@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
String parameter = httpServletRequest.getParameter("l");
Locale locale = Locale.getDefault();
System.out.println("这是locale:" + locale);
System.out.println("这是parameter:" + parameter);
if (!StringUtils.isEmpty(parameter)){
String[] split = parameter.split("_");
locale = new Locale(split[0], split[1]);
System.out.println(locale);
}
return locale;
}

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

}
}

登陆逻辑实现

小技巧:开发期间,模板引擎修改后想要实时生效

  1. 禁用模板引擎缓存
1
2
#禁用缓存
spring.thymeleaf.cache=false
  1. 页面修改完成后ctrl+f9:重新编译

在登陆页的表单中需要传值的标签上标识name属性,form表单中需要如下代码

1
<form class="form-signin" th:action="@{/user/login}" method="post">
  1. 将获取到的值使用post方式传至/user/login中,在controller层中需要一个方法去接收它,代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
public class LoginController {

@PostMapping(value = "/user/login")
// @RequestMapping(value = "/user/login",method = RequestMethod.POST)
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
Map<String,Object> map){
if (username.equals("123")&&password.equals("123")){
return "dashboard";
}else{
map.put("msg","用户名密码错误");
return "login";
}
}
}
  1. 若用户名或者密码出现错误,则返回错误信息,在登陆页代码如下:
1
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
  1. 为了防止登陆表单的重复提交,需要进行页面的重定向在视图控制类中写入以下代码,方便前台重定向到该页面
1
registry.addViewController("/main").setViewName("dashboard");
  1. 在登陆控制层中,return “redirect:/main”;重定向至/main请求,经由上述代码,进入dashboard页面

拦截器

将已经登陆的用户存在session中,如以下代码所示,若想从页面中获取session则用${session.loginUser}

1
2
3
4
5
6
7
8
9
if (username.equals("123")&&password.equals("123")){
//只要登陆了,用户便会存在session中
session.setAttribute("loginUser",username);
//为了防止表单重复提交,需要进行重定向
return "redirect:/main";
}else{
map.put("msg","用户名密码错误");
return "login";
}

新建一个登陆验证类,获取session信息进行验证,代码如下

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
package com.example.springbootweb.component;


import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 登陆检查
*/
//拦截器实现
public class LoginHandlerInterceptor implements HandlerInterceptor{

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginUser = request.getSession().getAttribute("loginUser");
if (loginUser == null){
//未登录
request.setAttribute("msg","您没有权限,请先登录!");
//将请求转至登陆页
request.getRequestDispatcher("/login").forward(request,response);
return false;
}else{
//已登陆,
return true;
}
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}
}

在mvc配置类中注册拦截器,用来拦截一些请求,代码如下

1
2
3
4
5
6
7
8
9
 //注册拦截器
//虽然springboot将静态资源映射过去了,不会被拦截,公共资源有可能会被拦截(技术不够,未能解决,只能退而求其次,不拦截所有,只拦截部分)
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截任意路径下的任意请求,excludePathPatterns是排除一些请求
//registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
//.excludePathPatterns("/login","/","/user/login");
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/main");
}

员工列表

  1. RestfulCRUD:CRUD满足Rest风格;

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

普通CRUD RestfulCRUD
查询 getEmp emp—GET
添加 addEmp?xxx emp—POST
修改 updateEmp?id=xxx&xxx=xxx emp—PUT
删除 deleteEmp?id=1 emp/{id}—DELETE
  1. 实验的请求架构
请求URL 请求方式
查询所有 emps GET
查询单个 emp/{id} GET
添加页面 emp GET
添加员工 emp POST
来到修改页面(查出员工信息回显) emp/{id} GET
修改员工 emp PUT
删除员工 emp/{id} DELETE
  1. 员工列表

thymeleaf公共页面元素抽取

1
2
3
4
5
6
1.抽取公共元素
<div th:fragment="copy">
&copy; 2011 The Good Thymes Virtual Grocery
</div>
2.引入公共片段
<div th:insert="~{footer :: copy}"></div>

三种引入功能片段的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
或者
<div th:insert="footer :: #copyid"></div>
<div th:replace="footer :: #copyid"></div>
<div th:include="footer :: #copyid"></div>

效果
<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>

注意:
若使用th:xxx进行引入,可以不用写~{}
行内写法:[(~{})]

参数化片段

引入片段时传入参数,例如,当获取某个公共标签时,若想修改其中一个标签的class则可以利用如下代码,将参数传入公共标签页

1
<div th:replace="commons/common::lefter(activeUrl='emps')"></div>

在公共标签页接收后,进行如下判断,再选择class的内容

1
2
3
<a class="nav-link"
th:class="${activeUrl=='main'?'nav-link active':'nav-link'}"
th:href="@{/main}">

遍历数据

将控制层放入公共域中的数据拿出,进行遍历,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
<tr th:each="emps:${emps}">
<td th:text="${emps.id}"></td>
<td>[[${emps.lastName}]]</td>
<td th:text="${emps.email}"></td>
<td th:text="${emps.gender} == 0?'女':'男'"></td>
<td th:text="${emps.department.departmentName}"></td>
<td th:text="${#dates.format(emps.birth,'yyyy-MM-dd HH:mm')}"></td>
<td>
<a class="btn btn-sm btn-primary">编辑</a>
<button class="btn btn-sm btn-danger deleteBtn">删除</button>
</td>
</tr>

添加实现

当点击添加按钮时,按post方式提交请求,将数据传值给后台时,自动将其封装成一个对象,然后将对象存入,注意,返回总览页面时,需要重定向至该页面,页面代码如下所示:

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

controller层代码如下所示:

1
2
3
4
5
6
7
@PostMapping("/emp")
public String addEmp(Employee employee){
//来到员工列表页面
//redirect:表示重定向到一个地址,forward:表示转发到一个地址
employeeDao.save(employee);
return "redirect:/emps";
}

注意:提交数据格式不对,会引起报错,如日期,所以需要进行日期格式化