Spring Boot的Web入门

Spring Boot与Web开发

使用SpringBoot

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

一. SpringBoot 静态资源的映射规则

WebMvcAutoConfiguration自动配置类

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:/META-INF/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(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
        }
    }
}

ResourceProperties资源配置类

@ConfigurationProperties(
    prefix = "spring.resources",
    ignoreUnknownFields = false
)
public class ResourceProperties {
    ...
    //可以设置和金泰资源有关的参数, 缓存时间等
}

WelcomePageHandlerMapping欢迎页映射

@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
    welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
    return welcomePageHandlerMapping;
}

  1. 所有/webjars/**, 都去classpath:/META-INF/resources/webjars/下寻找资源

    webjars : 以jar包的方式引入静态资源, 官方网站

    可以使用maven形式导入

在这里插入图片描述

其访问路径为: localhost:8080/webjars/jquery/3.5.1/jquery.js

  1. /** : 访问当前项目任何资源(静态资源的文件夹)

    classpath:/META-INF/resources/
    classpath:/resources/
    classpath:/static/
    classpath:/public/
    / : 当前项目的根路径
    
  2. 欢迎页: 静态资源文件下的所有index.html页面, 被/** 映射

    localhost:8080/ 默认找 index页面


二. 模板引擎

模板引擎有: JSP, Velocity, Freemark, Thymeleaf 等等…

SpringBoot推荐使用Thymeleaf

官方文档

1. 引入Thymeleaf

引入启动器

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

修改thymeleaf的版本

<properties>
   <java.version>11</java.version>
   <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
   <!-- 布局功能的支持程序 -->
   <thymeleaf-layout-dialect.version>2.5.1</thymeleaf-layout-dialect.version>
</properties>

2. thymeleaf使用

导入thymeleaf的名称空间

<html lang="ch" xmlns:th="http://www.thymeleaf.org">
<h1 id="h101" class="myH1" th:id="msg" th:class="myMsg" th:text="${msg}">这是显示欢迎信息</h1>

3. 语法规则

序号特征属性
1片段包含(jsp:includ)th:insert th:replace
2片段迭代(c:forEach)th:each
3条件评估(c:if)th:if th:unless th:switch th:case
4局部变量定义(c:set)th:object th:with
5常规属性修改th:attr th:attrprepend th:attrappend
6特定属性修改th:value th:href th:src ...
7文字(标签正文修改)th:text(转义)th:utext(不转义)
8声明片段th:fragment
9碎片清除th:remove

4. 表达式

  • 简单表达式:

    • 变量表达式: ${...}

      <p>Today is: <span th:text="${today}">13 february 2011</span>.</p>
      
    • 选择变量表达式: *{...} - 和${}在功能上是一样的

      <p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
      
    • 消息表达: #{...} - 获取国际化内容

      <p>
        Today is: <span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>
      </p>
      
    • 链接URL表达式: @{...} - 定义URL

      <a th:href="@{${url}(orderId=${o.id})}">view</a>
      <a th:href="@{'/details/'+${user.login}(orderId=${o.id})}">view</a>
      
    • 片段表达式: ~{...}

      <div th:insert="~{commons :: main}">...</div>
      
  • 文字

    • 文本文字:'one text''Another one!',…
    • 号码文字:0343.012.3,…
    • 布尔文字:truefalse
    • 空文字: null
    • 文字标记:onesometextmain,…
  • 文字操作:

    • 字符串串联: +
    • 文字替换: |The name is ${name}|
  • 算术运算:

    • 二元运算符:+-*/%
    • 减号(一元运算符): -
  • 布尔运算:

    • 二元运算符:andor
    • 布尔否定(一元运算符): !not
  • 比较和平等:

    • 比较:><>=<=gtltgele
    • 等号运算符:==!=eqne
  • 条件运算符:

    • 如果-则: (if) ? (then)
    • 如果-则-否则: (if) ? (then) : (else)
    • 默认: (value) ?: (defaultvalue)
  • 特殊令牌:

    • 无操作: _

实例:

<!DOCTYPE html>
<html lang="ch" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Success</title>
</head>
<body>
<h1>Success!</h1>
<!-- th:text 将<h1>中的文本内容设置为指定的值 -->
<h1 id="h101" class="myH1" th:id="msg" th:class="myMsg" th:text="${msg}">这是显示欢迎信息</h1>
<hr>
<div th:text="${msg}"></div>
<div th:utext="${msg}"></div>
<hr>
<h4 th:each="user : ${users}" th:text="${user}"></h4>
<hr>
<h4>
    <span th:each="user : ${users}">[[${user}]]</span>
</h4>
</body>
</html>

三. 扩展SpringMVC

编写一个配置类@Configuration, 是WebMvcConfigurerAdapter类型; 不能标注@EnableWebMvc

/**
 * 使用WebMvcConfigurerAdapter可以扩展SpringMVC的功能
 * @Author Harlan
 * @Date 2020/10/5
 */
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //访问/springboot, 跳转到success.jsp
        registry.addViewController("/springboot").setViewName("success");
    }
}

其保留了所有的自动配置, 也能用我们的扩展配置

全面接管SpringMVC

SpringBoot对SpringMVC的自动配置不使用, 使用用户自己的配置

只需要在配置类中添加@EnableWebMvc注解



四. 国际化

  1. 编写国际化配置文件
  2. 使用ResourceBundleMessageSource管理国际化资源文件
  3. 在页面使用fmt:message取出国际化内容

步骤:

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

在这里插入图片描述

其中包括一个默认配置login.properties

文件命名为规则: 页面名+语言缩写+国家简写

其文件内容为:在这里插入图片描述

可点击IDE下方的ResourceBundle按钮进行多个文件快速编辑:在这里插入图片描述

编辑效果如图:在这里插入图片描述

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

    指定基础名

    spring:
      messages:
        basename: i18n.login
    
  2. 在页面中使用#{...}获取国际化的值

    <input type="text" placeholder="Username" th:placeholder="#{login.username}">
    <button type="submit">[[#{login.btn}]]</button>
    

    其根据浏览器语言设置的信息切换了国际化


自定义国际化

国际化实现原理是通过获取请求头中Accept-Language: zh-CN,zh参数在这里插入图片描述

我们可以通过实现LocaleResolver接口中的方法, 获取到请求体中的信息进行自定义国际化

public interface LocaleResolver {
    Locale resolveLocale(HttpServletRequest var1);

    void setLocale(HttpServletRequest var1, @Nullable HttpServletResponse var2, @Nullable Locale var3);
}

resolveLocale方法返回一个Locale对象

setLocale方法可以设置Locale对象

实现LocaleResolver接口

请求路径中携带关于地区语言的参数信息

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

HttpServletRequest中获取请求参数

通过构造器实例化Locale对象, 传入参数, 并返回

/**
 * 在链接上携带区域信息
 * @Author Harlan
 * @Date 2020/10/5
 */
public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        Locale locale = null;
        String l = httpServletRequest.getParameter("l");
        if (!StringUtils.isEmpty(l)){
            System.out.println(l);
            //获取国际语言信息
            String[] local = l.split("_");
            locale = new Locale(local[0], local[1]);
        }else {
            //获取默认的信息
            locale = Locale.getDefault();
        }
        return locale;
    }

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

    }
}

最后将自定义的国际化类注入到容器中(扩展Mvc类)

/**
 * 使用WebMvcConfigurerAdapter可以扩展SpringMVC的功能
 * @Author Harlan
 * @Date 2020/10/5
 */
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {

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

注意: 其方法名必须为 localeResolver


五. 自定义拦截器

拦截器需要实现HandlerInterceptor接口, 根据业务需求重写其中的方法

在目标方法前执行: preHandle

在目标方法执行后响应视图前执行: postHandle

在响应视图后执行: afterCompletion

根据拦截用户是否登录需求示例:

public class LoginHandlerInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object user = request.getSession().getAttribute("loginUser");
        if (user == null){
            //未登录, 返回登录页面
            request.setAttribute("msg", "没有权限,请先登录");
            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 {
    }
}

在MVC扩展配置类中, 添加自定义的拦截器

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
        return new WebMvcConfigurerAdapter() {

            //配置拦截器
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/user/login");
            }

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

配置需要拦截的路径, 排除拦截的路径即可.


六. SpringBoot错误处理

1. SpringBoot默认的错误处理

当PC浏览器访问服务器或发送请求时发生错误, SpringBoot会默认返回一个空白页面在这里插入图片描述


如果是其它客户端, 默认响应一个json数据

在这里插入图片描述


2. 定制错误响应

  1. 定制错误页面

    有模板引擎的情况下:将错误页面命名为错误状态码.html, 并放在模板引擎的/error文件夹下, 如发生此状态码, 即可响应对应的html页面 –error/错误状态码.html.

    • 如命名为4xx.html则表示已4开头的错误状态码都响应此页面(优先寻找精确的状态码页面)

    • 获取错误信息

      timestamp: 时间戳

      satatus: 状态码

      error: 错误提示

      exception: 异常对象

      message: 异常消息

      errors: JSR303数据校验错误

    <h1>status:[[${status}]]</h1>
    <h2>status:[[${timestamp}]]</h2>
    
  2. 定制错误json数据

    通过定义一个异常处理控制器, 捕获需要处理的异常信息, 通过json返回, 但没有自适应效果(PC和其它客户端都会返回json数据)

    @ControllerAdvice
    public class MyExceptionHandler {
    
        @ResponseBody
        @ExceptionHandler(HelloException.class)
        public Map<String, Object> handleException(Exception e){
            Map<String, Object> map = new HashMap<>();
            map.put("code", "hello.notExist");
            map.put("message", e.getMessage());
            return map;
        }
    }
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值