SpringBoot-Web开发
Posted 滑稽404#
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot-Web开发相关的知识,希望对你有一定的参考价值。
文章目录
一、静态资源映射
1、webjars
被打成jar包的静态资源
/webjars/**:
所有webjars资源都去 classpath:/META-INF/resources/webjars/ 下找
根据webjars官网,添加jquery依赖
访问的时候,只需要写webjars下面的资源名称即可
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.0</version>
</dependency>
资源存放路径如下:
2、访问当前项目编写的静态资源
“/**”:访问当前文件夹的任何资源(静态资源文件夹)
classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
"/":当前项目的根路径
3、欢迎页
静态资源文件夹里的所有index.html都会被映射到/**
4、图标
所有的**/favicon.ico都在静态资源文件夹里找
二、thymeleaf
因为SpringBoot使用了内嵌的tomcat,使用jsp不太容易,官方推荐使用thymeleaf模板引擎
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2、更改版本
因为boot的启动器已经设置好了关于thymeleaf的版本(2.x),所以改版本需要覆盖掉他原有的
<properties>
<springboot-thymeleaf.version>3.0.9.RELEASE</springboot-thymeleaf.version>
<thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
</properties>
3、视图解析
@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";
会解析 classpath:/templates/ 下的html视图
4、thymeleaf使用
(1)添加命名空间
xmlns:th="http://www.thymeleaf.org"
不加命名空间不会影响程序,但是不会有提示功能
(2)常用语法
@RequestMapping("/success")
public String success(Model model,Map<String,Object> map){
model.addAttribute("hello","hello3");
model.addAttribute("users",Arrays.asList("张三","李四","王五"));
map.put("list",Arrays.asList("数据结构","计组","计网","操作系统"));
return "success";
}
<body>
<div th:text="${hello}"></div>
<ul>
<li th:each="user:${users}" th:text="${user}"></li>
</ul>
<ul>
<li th:each="obj:${list}">[[${obj}]]</li>
</ul>
</body>
三、MVC配置
WebMvcAutoConfiguration会将自动配置和自己拓展的配置全部组合起来使用
1、拓展mvc配置
配置类添加@Configuration注解,实现WebMvcConfigurer接口表明就是MVC其中的一个组件了
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("success");
}
}
2、全面接管MVC
在配置类中添加@EnableWebMvc注解
该注解:如果容器中有自己配置的mvc,则自动配置取消,只使用自己的
但不推荐使用,因为默认的自动配置比较全,最好是自动配置和拓展配置组合使用
四、引入资源
- 静态资源(公共资源css、js、Jquery、图片等)放在static文件夹下
- 视图页面放在template交给thymeleaf模板引擎进行解析
- 配置首页
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
WebMvcConfigurerAdapter已经被淘汰,推荐方法是实现WebMvcConfigurer
- 资源路径通过thymeleaf绑定,因为资源路径开始指定的绝对路径,如果资源位置发生改变(contextPath),thymeleaf会自动加上
href="asserts/css/bootstrap.min.css" ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ <link th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet"> 或者可以通过webjars直接访问META-INF下的webjars静态资源 @{/webjars/bootstrap/5.0.1/css/bootstrap.css}
如果我更改了context-path
server.servlet.context-path=/web
通过thymeleaf绑定的资源路径会自动改变,非常方便
五、国际化
1、编写国际化配置文件
文件格式:xxx_语言_国家代码
2、配置文件指定国际化文件名
(1)源码
@Bean
@ConfigurationProperties(prefix = "spring.messages")
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;
}
String basename = context.getEnvironment().getProperty("spring.messages.basename", "messages");
(2)配置
spring.messages.basename=i18n.login
2、页面获取国际化文件的值
message采用#{}获取值
th:text="#{login.tip}"
th:text="#{login.username}"
th:placeholder="#{login.username}"
<input type="checkbox" value="remember-me"> [[#{login.remember}]]
页面根据语言信息切换了国际化
3、原理
localeResolver(区域信息解析)
WebMvcAutoConfiguration帮我们配置了localeResolver组件
@Override
@Bean
//若容器中没有自己配置,就生效
@ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME)
@SuppressWarnings("deprecation")
public LocaleResolver localeResolver() {
if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.webProperties.getLocale());
}
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
Locale locale = (this.webProperties.getLocale() != null) ? this.webProperties.getLocale()
: this.mvcProperties.getLocale();
localeResolver.setDefaultLocale(locale);
return localeResolver;
}
AcceptHeaderLocaleResolver根据请求头里的语言信息,切换了国际化
我们可以通过@ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME)特性,
若没有配置,则该组件生效;若配置了,则用用户自己的
自己配置locale来切换国际化(点中文和英文按钮切换)
4、自己配置国际化组件
(1)传识别参数
<a class="btn btn-sm" th:href="@{/index.html(languege='ch_Cn')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(languege='en_Us')}">English</a>
(2)编写LocalResolver
//传区域信息进行解析
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
System.out.println(1);
Locale locale=Locale.getDefault();//如果参数没有。就用系统默认的
String languege = request.getParameter("languege");
System.out.println(2);
if(!StringUtils.isEmpty(languege)){
String[] s = languege.split("_");
//语言 国家代码
System.out.println(s[0]+s[1]);
locale=new Locale(s[0],s[1]);
}
System.out.println(3);
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
Locale locale=Locale.getDefault();//如果参数没有。就用系统默认的(根据请求头语言参数判断)
如果返回locale为空会出现异常
(3)交给容器
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
//容器托管
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
用户自己配置了区域信息解析器组件,自动配置就不生效了
配置好后重启服务器,就可以通过按钮切换国际化
六、登录拦截
1、开发技巧
开发过程中,修改的thymeleaf页面要实时生效:
- 禁用thymeleaf缓存
spring.thymeleaf.cache=false
- 页面修改后ctrl+f9重新编译
2、视图解析
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/login").setViewName("login");
registry.addViewController("/main").setViewName("dashboard");
}
3、controller
@Controller
public class LoginController {
@PostMapping("/user/login")
public String login(String username, String password, Map<String,Object> map, HttpSession session){
if(username.equals("admin")&&password.equals("12345")){
session.setAttribute("token",username);
return "redirect:/main";
}
map.put("msg","用户密码错误");
return "login";
}
}
登录成功,防止表单重复提交,可以使用重定向跳转
4、信息显示
如果msg不为空 显示msg
<p style="color:red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
5、编写拦截器
public class LoginHandlerIntercepter implements HandlerInterceptor {
//执行请求前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object token = request.getSession().getAttribute("token");
if(token==null){
//登录失败
request.setAttribute("msg","没有权限");//不要用session,thymeleaf不能通过strings判定session
request.getRequestDispatcher("/index.html").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 {
}
}
不要session存放msg,strings.isEmpty不能判断session
6、WebMvcConfigurer添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//使用自己编写的拦截器拦截所有资源
registry.addInterceptor(new LoginHandlerIntercepter()).addPathPatterns("/**").
//排除入口和登录
excludePathPatterns("/user/login","/index.html","/").
//排除静态
excludePathPatterns("/asserts/**");
}
注意:springboot1不用排除静态,但是现在的版本好像要自己排除了
7、Restful风格
CRUD满足Rest风格
URI:/资源名称/资源标识 HTTP请求方式区分对资源CRUD操作
同样的资源名称,根据资源标识和请求方式的不同进入不同请求
七、抽取公共页
1、公共片段
<nav th:fragment="topbar" class="col-md-2 d-none d-md-block bg-light sidebar">
给公共片段取名
th:fragment="topbar"
公共页替换 ~{模板名::片段名}
<div th:replace="~{dashboard::topbar}"></div>
取id sidebar
<nav id="sidebar" class="col-md-2 d-none d-md-block bg-light sidebar">
~{模板名::选择器}
~{模板名::#id名}
<div th:replace="~{dashboard::#sidebar}"></div>
2、点击高亮
通过公共片段添加判断语句来增加高亮
th:class="${activeUri=='main'?'nav-link active':'nav-link'}"
main高亮
<div th:replace="~{commons/bar::#sidebar(activeUri='main')}"></div>
emps高亮
<div th:replace="~{commons/bar::#sidebar(activeUri='emps')}"></div>
3、日期数据
mvc默认的格式yyyy/MM/dd
其他的格式会报错
这时候就需要配置文件中添加格式
spring.mvc.date-format=yyyy-MM-dd
4、添加修改两用页面
- 去添加页面get
- 添加请求post
- 去修改同去添加
- 修改请求用put
@GetMapping("/emp")
public String toAdd(Model model){
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("depts",departments);
return "emp/add";
}
@PostMapping("/emp")
public String add(Employee e){
employeeDao.save(e);
return "redirect:/emps";
}
@GetMapping("/emp/{id}")
public String toUpd以上是关于SpringBoot-Web开发的主要内容,如果未能解决你的问题,请参考以下文章