spring boot的学习--Springboot的Web开发(3)

news2024/9/21 10:55:11

1. 简介

1.1 创建springboot应用,选中我们需要的模块

1.2 springBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来

1.3 自己编写业务代码

顺便回顾下上一篇的自动装配

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

2 springBoot对静态资源的映射规则

2.1 Springboot对静态资源的映射规则

      WebMvcAuotConfiguration:

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

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
     if (!this.resourceProperties.isAddMappings()) {
           logger.debug("Default resource handling disabled");
           return;
      } 
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/**")) {
     customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META‐INF/resources/webjars/").setCachePeriod(cachePeriod));
} 
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
//静态资源文件夹映射
if (!registry.hasMappingForPattern(staticPathPattern)) {
      customizeResourceHandlerRegistration(registry.
addResourceHandler(staticPathPattern).addResourceLocations(this.resourceProperties.getStaticLocations()).setCachePeriod(cachePeriod));
}
} /
/配置欢迎页映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
       ResourceProperties resourceProperties) {
       return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
//配置喜欢的图标
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration {
       private final ResourceProperties resourceProperties;
       public FaviconConfiguration(ResourceProperties resourceProperties) {
            this.resourceProperties = resourceProperties;
}
 @Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
       SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
       mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
       //所有 **/favicon.ico
            mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
faviconRequestHandler());
return mapping;
} 
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
       ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
       requestHandler.setLocations(this.resourceProperties.getFaviconLocations());
       return requestHandler;
 }
}

2.2 所有/webjars/**,都去classpath:/META-INF/resources/webjars/ 找资源;

 webjars:以jar包的方式引入静态资源;WebJars - Web Libraries in Jars

                                   localhost:8080/webjars/jquery/3.3.1/jquery.js

2.3 那如何引入jquert-webjar呢?

             在访问的时候只需要写webjars下面资源的名称即可

<!‐‐引入jquery‐webjar‐‐>在访问的时候只需要写webjars下面资源的名称即可
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

 2.4 "/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射

"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径

             localhost:8080/abc === 去静态资源文件夹里面找abc

2.5 欢迎页; 静态资源文件夹下的所有index.html页面;被"/**"映射;(localhost:8080/ index页面

3. 模版引擎

JSPVelocityFreemarkerThymeleaf

SpringBoot推荐的Thymeleaf

         语法更简单,功能更强大;

3.1 如何引入thymeleaf呢

        在pom.xml中引入:

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

 注意:

        从spring父文件中能看到Springboot2.0.1所使用的thymeleaf版本是3.0.9

        springBoot启动的时候会自动配置

                org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration

而从ThymeleafAutoConfiguration的源代码中我们可以得知ThymeleafProperties

中配置了Thymeleaf的规则

3.2 ThymeleafProperties中都配置了哪些呢?

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";
    private Charset encoding;
    private boolean cache;

 我们使用html作为模版,而且默认的前缀是放在classpath:/template/下,后缀是.html

  当然这些属性我们都可以通过application.properties来修改我们采用默认即可。

3.3 举个例子

  3.3.1  在template下创建一个success.html

  3.3.2  在html中引入thymeleaf的命名空间

        <html lang="en" xmlns:th="http://www.thymeleaf.org">

  3.3.3 创建一个Controller提供一个访问的方法

@RequestMapping("/success")
public String hello(Model model){
    model.addAttribute("hello","<h1>renliang</h1>");
    return "success";
}

  3.3.4    在thymeleaf模板中取值

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Title</title>
</head>
<body>
<div  th:text="${hello}"> </div>
</body>
</html>

4. 现在来学习下Thymeleaf语法

4.1 变量表达式

 变量表达式即OGNL表达式或Spring EL表达式(Spring术语中也叫model attributes)

        如下所示: ${session.user.name}

       它们将以HTML标签的一个属性来表示:

 

<span th:text="${book.author.name}"> 

4.2 选择(星号作为表达式)

选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如下: *{customer.name}

被指定的objectth:object属性定义:

<div th:object="${book}"> 
 ... 
 <span th:text="*{title}">...</span> 
 ... 
</div>

4.3 文字国际化表达式

    文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用Key索引Value,还可以提供一组参数(可选).

           #{main.title}

4.4 URL表达式

     URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL

        重写。不需要指定项目名字
        @{/order/list} 

        URL还可以设置参数:@{/order/details(id=${orderId})} 

    让我们看这些表达式:

<form th:action="@{/createOrder}"> 
<a href="main.html" rel="external nofollow" th:href="@{/main}" rel="external n

4.5 表达式都支持哪些语法呢?

字面(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)
    例如:'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

4.6 常用的thymeleaf标签

好了,最后整体来个例子吧!       

   模板:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Title</title>
</head>
<body>
<div  th:text="${hello}" th:id="${hello.toUpperCase()}">xxxx</div>
<input th:value="${user.getUsername()}">
<hr>
<div th:object="${user}">
<span th:text="*{username}"></span>

</div>


<a th:href="" th:if="${user.getAge() == 2}" >年龄</a>

<a  th:class="${user.getAge() > 2}?'class1':'class2'" >年龄</a>

<p th:if="${user.score >= 60 and user.score < 85}">B</p>
<p th:if="${user.score < 60}">C</p>
<p th:if="${user.score > 85}">优秀</p>


<span th:switch="${user.gender}">
    <p th:case="1">男</p>
    <p th:case="2">女</p>
</span>


<table>

    <tr th:each="a,aState:${uList}">
        <td th:text="${a.username}"></td>
        <td th:text="${a.password}"></td>
        <td th:text="${aState.index}"></td>
    </tr>
</table>

</body>
</html>

  Controller中给的数据:

@RequestMapping("/success")
public String hello(HttpServletRequest req, HttpSession httpSession, Model model){
    model.addAttribute("hello","<h1>renliang</h1>");
    User user = new User();
    user.setPassword("111");
    user.setUsername("renliang");
    user.setAge(1);
    user.setScore(78);
    user.setGender(2);
    List<User> uList = new ArrayList<>();
    for (int i = 0; i < 10; i++){
        User u = new User();
        u.setUsername("renliang"+i);
        u.setPassword("111"+i);

        uList.add(u);
    }

   // httpSession.setAttribute("user", user);
    model.addAttribute("user", user);
    model.addAttribute("uList", uList);
    return "success";
}

5. Springboot整合springmvc

 官网资料:  https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc

 (学习springmvc和springboot的自动配置我们必须对springmvc的组件足够了解,起码知道怎么用。Springmvc的组件基本都被springboot来做了自动的配置。

5.1 springmvc的自动配置管理

中央转发器(DispatcherServlet)
控制器
视图解析器
静态资源访问
消息转换器
格式化
静态资源管理

5.2 中央转发器(DispatcherServlet)

注意

DispatcherServlet的自动注册:
    Spring Boot会自动注册并配置DispatcherServlet作为前端控制器,它是Spring MVC的核心组件,负责接收HTTP请求并分发到相应的处理器(Controller)

 XML不需要配置下面的

<servlet>
    <servlet-name>chapter2</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>chapter2</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

     中央转发器被springboot自动接管,不再需要我们在web.xml中配置,我们现在的项目也不是web项目,也不存在web.xml,

 在这里自动配置的哦 -》

org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\

5.3 控制器(也就是Controller)

        控制器Controller在springboot的注解扫描范围内自动管理

5.4 视图解析器自动管理

        Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

ContentNegotiatingViewResolver:组合所有的视图解析器的

      以前的配置文件无需配置

<bean id="de" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"></property>
    <property name="suffix" value="*.jsp"></property>
</bean>

源码:

public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
    ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
 resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
    resolver.setOrder(-2147483648);
    return resolver;
}

注意:当我们做文件上传的时候我们也会发现multipartResolver自动被配置好的

 页面:

<form action="/upload" method="post" enctype="multipart/form-data">
    <input name="pic" type="file">
    <input type="submit">
</form>

Controller:

@ResponseBody
@RequestMapping("/upload")
public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){
    String contentType = file.getContentType();
    String fileName = file.getOriginalFilename();
    /*System.out.println("fileName-->" + fileName);
    System.out.println("getContentType-->" + contentType);*/
    //String filePath = request.getSession().getServletContext().getRealPath("imgupload/");
    String filePath = "D:/imgup";
    try {
        this.uploadFile(file.getBytes(), filePath, fileName);
    } catch (Exception e) {
        // TODO: handle exception
    }

    return "success";
}


public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
    File targetFile = new File(filePath);
    if(!targetFile.exists()){
        targetFile.mkdirs();
    }
    FileOutputStream out = new FileOutputStream(filePath+fileName);
    out.write(file);
    out.flush();
    out.close();
}

文件上传大小可以通过配置来修改---》打开application.properties, 默认限制是10MB,我们可以任意修改

5.5 消息转换和格式化

        5.5.1 Springboot自动配置了消息转换器

   格式化转换器的自动注册

时间类型我们可以在这里修改

在配置文件中指定好时间的模式我们就可以输入了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1916351.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue 搭建 pinia

文章目录 环境设置存储读取数据【 storeToRefs】借助storeToRefs将store中的数据转为ref对象&#xff0c;方便在模板中使用【getters】当state中的数据&#xff0c;需要经过处理后再使用时&#xff0c;可以使用getters配置【$subscribe】通过 store 的 $subscribe() 方法侦听 s…

韦尔股份:深蹲起跳?

利润大增7倍&#xff0c;是反转信号还是回光返照&#xff1f; 今天我们聊聊光学半导体龙头——韦尔股份。 上周末&#xff0c;韦尔股份发布半年业绩预告&#xff0c;预计上半年净利润13至14亿&#xff0c;同比增幅高达 754%至 819%。 然而&#xff0c;回首 2023 年它的净利仅 …

代码随想录算法训练营第二十九天

452. 用最少数量的箭引爆气球 这道题目我原本的想法是只要当前的气球半径范围在已有的箭头能够击穿的气球半径内就可以实现 但是 箭射出去的地方是一个值 而不是一个范围 因此有相同的重叠范围的许多气球并一定都有相同的值&#xff0c;因此这种方法不可取 这题的主要局部最…

『Django』自带的后台

theme: smartblue 本文简介 点赞 关注 收藏 学会了 上一篇讲了 Django 操作 MySQL 的方法&#xff0c;讲了如何创建模型&#xff0c;如何对数据库做增删改查的操作。但每次修改数据都要写代码&#xff0c;多少有点麻烦。 有没有简单一点的方法呢&#xff1f; 有的有的&#…

kotlin Flow 学习指南 (三)最终篇

目录 前言Flow生命周期StateFlow 替代LiveDataSharedFlow其他常见应用场景处理复杂、耗时逻辑存在依赖关系的接口请求组合多个接口的数据 Flow使用注意事项总结 前言 前面两篇文章&#xff0c;介绍了Flow是什么&#xff0c;如何使用&#xff0c;以及相关的操作符进阶&#xff…

leetcode 1421 净现值查询(postgresql)

需求 表: NPV ---------------------- | Column Name | Type | ---------------------- | id | int | | year | int | | npv | int | ---------------------- (id, year) 是该表主键. 该表有每一笔存货的年份, id 和对应净现值的信息. 表: Queries ---------------------- …

Nginx -Web服务器/反向代理/负载均衡

文章目录 一、web服务1.1 nginx安装1.2 配置文件1.3 Nginx处理Web机制 二、反向代理三、负载均衡3.1 分类3.2 负载相关配置文件3.3 keepalive 提高吞吐量3.4 配置浏览器缓存 附、JMeter性能测试工具 以赛促学内容,大概率感觉会使用nginx做web服务,特对nginx做总结归纳. Nginx是…

AI in Finance 金融领域AI应用-基于DeepNLP AI App Store 真实用户评论打分和排名

AI在金融领域应用 AI in Finance 金融服务领域的AI应用和传统的金融智能应用不同。传统金融智能应用包括如风险评估 (Risk assessment), 风险管理&#xff08;Risk management), 欺诈检测 (Fraud Detection&#xff09;等等。 通用AI大模型和人工智能应用如ChatGPT&#xff0c…

PyTorch复现PointNet——模型训练+可视化测试显示

因为项目涉及到3D点云项目&#xff0c;故学习下PointNet这个用来处理点云的神经网络 论文的话&#xff0c;大致都看了下&#xff0c;网络结构有了一定的了解&#xff0c;本博文主要为了下载调试PointNet网络源码&#xff0c;训练和测试调通而已。 我是在Anaconda下创建一个新的…

香蕉派BPI-Wifi6迷你路由器公开发售

Banana Pi BPI-Wifi6 Mini 公开发售。 Banana Pi BPI-Wifi6 Mini 开源路由器采用Triductor TR6560 TR5220 wifi SOC设计&#xff0c;是一款迷你尺寸的wifi6路由器解决方案。内置高性能双核ARM Cortec A9处理器用于WIFI报文转发或智能业务处理&#xff0c;内置高性能LSW和硬件N…

最新浪子授权系统网站源码 全开源免授权版本

最新浪子授权系统网站源码 全开源免授权版本 此版本没有任何授权我已经去除授权&#xff0c;随意二开无任何加密。 更新日志 1.修复不能下载 2.修复不能更新 3.修复不能删除用户 4.修复不能删除授权 5.增加代理后台管理 6.重写授权读取文件 7.修复已经知道漏洞 源码下…

pytorch-RNN实战-正弦曲线预测

目录 1. 正弦数据生成2. 构建网络3. 训练4. 预测5. 完整代码6. 结果展示 1. 正弦数据生成 曲线如下图&#xff1a; 代码如下图&#xff1a; 50个点构成一个正弦曲线随机生成一个0~3之间的一个值&#xff08;随机的原因是防止每次都从相同的点开始&#xff0c;50个点的正弦曲…

云手机批量操作使用场景,从Amazon、TK等软件分析

云手机目前所具备的群控&#xff0c;批量操作&#xff0c;自动化等功能&#xff0c;对于电商&#xff0c;软测&#xff0c;办公&#xff0c;直播&#xff0c;营销等行业有很好的减负作用。 针对于具体的海外APP&#xff0c;云手机具体可以做哪些事情来帮助我们减轻压力&#x…

Docker拉取失败,利用github将镜像推送到阿里云

GITHUB配置 fork https://github.com/tech-shrimp/docker_image_pusher 该项目到自己的账户下。 设置环境变量&#xff0c;其路径如下图 在该项目中 .github/workflows/docker.yaml 找到 env 标签 ALIYUN_REGISTRY: "${{ secrets.ALIYUN_REGISTRY }}"ALIYUN_NAME_S…

AC修炼计划(AtCoder Regular Contest 180) A~C

A - ABA and BAB A - ABA and BAB (atcoder.jp) 这道题我一开始想复杂了&#xff0c;一直在想怎么dp&#xff0c;没注意到其实是个很简单的规律题。 我们可以发现我们住需要统计一下类似ABABA这样不同字母相互交替的所有子段的长度&#xff0c;而每个字段的的情况有&#xff…

600Kg大载重起飞重量多旋翼无人机技术详解

600Kg大载重起飞重量的多旋翼无人机是一种高性能的无人驾驶旋翼飞行器&#xff0c;具有出色的载重能力和稳定的飞行特性。该无人机采用先进的飞行控制系统和高效的动力系统&#xff0c;能够满足各种复杂任务的需求&#xff0c;广泛应用于物资运输、应急救援、森林防火等领域。 …

西门子大手笔又买一家公司,2024年“两买”和“两卖”的背后……

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 更多的海量【智能制造】相关资料&#xff0c;请到智能制造online知识星球自行下载。 今年&#xff0c;这家全球工业巨头不仅精准出击&#xff0c…

MACOS查看硬盘读写量

一、安装Homebrew 按照提示进行安装 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"二、安装smartmontools brew install smartmontools三、查看硬盘读写量等信息 sudo smartctl -a /dev/disk0

Python8:线程和进程

1.并发和并行 并发&#xff1a;在逻辑上具备同时处理多个任务的能力&#xff08;其实每时刻只有一个任务&#xff09; 并行&#xff1a;物理上在同一时刻执行多个并发任务 2.线程与进程 一个进程管多个线程&#xff0c;一个进程至少有一个线程 python多线程是假的&#xf…

UML-各种图

什么是类图 定义系统中的类&#xff0c;描述类的内部结构&#xff08;属性、方法等&#xff09;&#xff0c;表示类之间的关系&#xff08;泛化、实现、依赖、关联、聚合、组合&#xff09;。 UML表示类图 上图中左侧图形是一个常见的类图&#xff0c; 类名&#xff1a;在顶…