• SpringBoot WEB开发


    目录

    ⚪核心!!!自动装配

    一、实现web开发要解决的问题?

    ⚪WebMvc的自动配置类

    二、导入静态资源

    1.通过Maven导入

     什么是webjars?

    2. publi、static、/**、resources

    🔥可以被识别到的目录 

    3.优先级

    三、首页

    ⭐WelcomePageHandlerMapping 

    四、Thymeleaf模板引擎

    1.什么是模板引擎?

    2.模板引擎的作用

    3.引入thymeleaf依赖 

    ThymeleafProperties 源码 

    3.使用

    五、Thymeleaf语法

    1.thymeleaf 中文文档

    2.thymeleaf 属性优先级

    3.Thymeleaf标准表达式语法(Thymeleaf Standard Expression syntax)。


    ⚪核心!!!自动装配

    springboot到底帮我们配置了什么?我们能不能进行修改?能不能扩展?

    • xxxxAutoConfiguration..向容器中自动配置组件
    • xxxxProperties:自动配置类,装配配置文件中自定义的一些内容

    一、实现web开发要解决的问题?

    • 静态资源的导入
    • 首页(index.html)
    • jsp,模板引擎Thymeleaf
    • 装配和扩展SpringMVC
    • CRUD
    • 拦截器
    • 国际化(中英文切换)

    ⚪WebMvc的自动配置类

    WebMvcAutoConfiguration
    1. @Override
    2. public void addResourceHandlers(ResourceHandlerRegistry registry) {
    3. if (!this.resourceProperties.isAddMappings()) {
    4. logger.debug("Default resource handling disabled");
    5. return;
    6. }
    7. addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    8. addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
    9. registration.addResourceLocations(this.resourceProperties.getStaticLocations());
    10. if (this.servletContext != null) {
    11. ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
    12. registration.addResourceLocations(resource);
    13. }
    14. });
    15. }
    16. private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
    17. addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
    18. }
    19. private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, Consumer customizer) {
    20. if (registry.hasMappingForPattern(pattern)) {
    21. return;
    22. }
    23. ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
    24. customizer.accept(registration);
    25. registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
    26. registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
    27. registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
    28. customizeResourceHandlerRegistration(registration);
    29. }

    二、导入静态资源

    1.通过Maven导入

     什么是webjars?

    WebJars是被打包成JAR文件 (Java Archive)形式的客户端web资源库(例如:jQuery、Bootstrap等)。即WebJars是库,是各种web资源库,打包成jar文件形式。 

    webjars官网:WebJars - Documentation

    具体参考:SpringBoot之使用WebJars - 简书 (jianshu.com)

    复制并添加到pom.xml中

    启动项目,在地址栏输入jquery文件路径localhost:8080/webjars/github-com-jquery-jquery/3.6.0/jquery.js 

    2. publi、static、/**、resources

    🔥可以被识别到的目录 

    测试

    结果:

    3.优先级

     resource  >  static  > public

    三、首页

    ⭐WelcomePageHandlerMapping 

    1. /**
    2. * An {@link AbstractUrlHandlerMapping} for an application's welcome page. Supports both
    3. * static and templated files. If both a static and templated index page are available,
    4. * the static page is preferred.
    5. *
    6. * @author Andy Wilkinson
    7. * @author Bruce Brouwer
    8. */
    9. final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {
    10. private static final Log logger = LogFactory.getLog(WelcomePageHandlerMapping.class);
    11. private static final List MEDIA_TYPES_ALL = Collections.singletonList(MediaType.ALL);
    12. WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
    13. ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
    14. if (welcomePage != null && "/**".equals(staticPathPattern)) {
    15. logger.info("Adding welcome page: " + welcomePage);
    16. setRootViewName("forward:index.html");
    17. }
    18. else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
    19. logger.info("Adding welcome page template: index");
    20. setRootViewName("index");
    21. }
    22. }
    23. private boolean welcomeTemplateExists(TemplateAvailabilityProviders templateAvailabilityProviders,
    24. ApplicationContext applicationContext) {
    25. return templateAvailabilityProviders.getProvider("index", applicationContext) != null;
    26. }
    27. private void setRootViewName(String viewName) {
    28. ParameterizableViewController controller = new ParameterizableViewController();
    29. controller.setViewName(viewName);
    30. setRootHandler(controller);
    31. setOrder(2);
    32. }
    33. @Override
    34. public Object getHandlerInternal(HttpServletRequest request) throws Exception {
    35. for (MediaType mediaType : getAcceptedMediaTypes(request)) {
    36. if (mediaType.includes(MediaType.TEXT_HTML)) {
    37. return super.getHandlerInternal(request);
    38. }
    39. }
    40. return null;
    41. }
    42. private List getAcceptedMediaTypes(HttpServletRequest request) {
    43. String acceptHeader = request.getHeader(HttpHeaders.ACCEPT);
    44. if (StringUtils.hasText(acceptHeader)) {
    45. return MediaType.parseMediaTypes(acceptHeader);
    46. }
    47. return MEDIA_TYPES_ALL;
    48. }
    49. }

    测试: 

    注意:在templates目录下的所有页面,只能通过controller来跳转  

    四、Thymeleaf模板引擎

    1.什么是模板引擎?

     模板引擎(用于Web开发)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

    前端交给我们的页面,是html页面。如果是我们以前开发,我们需要把他们转成jsp页面

    jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。

    jsp支持非常强大的功能,包括能写Java代码,但是SpringBoot项目是以jar的方式,不是war,且使用了Tomcat,因此默认是不支持jsp的

    SpringBoot推荐使用模板引擎:

    其实jsp就是一个模板引擎,还有用的比较多的freemarker,包括SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的,如图:

    2.模板引擎的作用

    模板引擎的作用就是我们来写一个页面模板,比如有值的,动态的,表达式。

    而这些值是我们在后台封装一些数据。然后把这个模板和这个数据交给模板引擎,模板引擎按照数据把表达式解析、填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去。

    Thymeleaf旨在提供⼀个优雅的、⾼度可维护的创建模板的⽅式。 为了实现这⼀⽬标,Thymeleaf建⽴在⾃然模板的概念上,将其逻辑注⼊到模板⽂件中,不会影响模板设计原型。 这改善了设计的沟通,弥合了设计和开发团队之间的差距。 做到了页面和展示的分离

    3.引入thymeleaf依赖 

    http://13. Build Systems (spring.io)

    spring-boot/pom.xml at v2.1.6.RELEASE · spring-projects/spring-boot · GitHub 

    1. <dependency>
    2. <groupId>org.thymeleafgroupId>
    3. <artifactId>thymeleaf-spring5artifactId>
    4. dependency>
    5. <dependency>
    6. <groupId>org.thymeleaf.extrasgroupId>
    7. <artifactId>thymeleaf-extras-java8timeartifactId>
    8. dependency>

    确认成功导入

    ThymeleafProperties 源码 

    1. @ConfigurationProperties(prefix = "spring.thymeleaf")
    2. public class ThymeleafProperties {
    3. private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8; //默认编码
    4. public static final String DEFAULT_PREFIX = "classpath:/templates/"; //前缀
    5. public static final String DEFAULT_SUFFIX = ".html"; //后缀必须以.html结尾
    6. /**
    7. * Whether to check that the template exists before rendering it.
    8. */
    9. private boolean checkTemplate = true;
    10. /**
    11. * Whether to check that the templates location exists.
    12. */
    13. private boolean checkTemplateLocation = true;
    14. /**
    15. * Prefix that gets prepended to view names when building a URL.
    16. */
    17. private String prefix = DEFAULT_PREFIX;
    18. /**
    19. * Suffix that gets appended to view names when building a URL.
    20. */
    21. private String suffix = DEFAULT_SUFFIX;
    22. /**
    23. * Template mode to be applied to templates. See also Thymeleaf's TemplateMode enum.
    24. */
    25. private String mode = "HTML";
    26. /**
    27. * Template files encoding.
    28. */
    29. private Charset encoding = DEFAULT_ENCODING;
    30. /**
    31. * Whether to enable template caching.
    32. */
    33. private boolean cache = true;
    34. /**
    35. * Order of the template resolver in the chain. By default, the template resolver is
    36. * first in the chain. Order start at 1 and should only be set if you have defined
    37. * additional "TemplateResolver" beans.
    38. */
    39. private Integer templateResolverOrder;
    40. /**
    41. * Comma-separated list of view names (patterns allowed) that can be resolved.
    42. */
    43. private String[] viewNames;
    44. /**
    45. * Comma-separated list of view names (patterns allowed) that should be excluded from
    46. * resolution.
    47. */
    48. private String[] excludedViewNames;
    49. /**
    50. * Enable the SpringEL compiler in SpringEL expressions.
    51. */
    52. private boolean enableSpringElCompiler;
    53. /**
    54. * Whether hidden form inputs acting as markers for checkboxes should be rendered
    55. * before the checkbox element itself.
    56. */
    57. private boolean renderHiddenMarkersBeforeCheckboxes = false;
    58. /**
    59. * Whether to enable Thymeleaf view resolution for Web frameworks.
    60. */
    61. private boolean enabled = true;
    62. private final Servlet servlet = new Servlet();
    63. private final Reactive reactive = new Reactive();
    64. public boolean isEnabled() {
    65. return this.enabled;
    66. }
    67. public void setEnabled(boolean enabled) {
    68. this.enabled = enabled;
    69. }
    70. public boolean isCheckTemplate() {
    71. return this.checkTemplate;
    72. }
    73. public void setCheckTemplate(boolean checkTemplate) {
    74. this.checkTemplate = checkTemplate;
    75. }
    76. public boolean isCheckTemplateLocation() {
    77. return this.checkTemplateLocation;
    78. }
    79. public void setCheckTemplateLocation(boolean checkTemplateLocation) {
    80. this.checkTemplateLocation = checkTemplateLocation;
    81. }
    82. public String getPrefix() {
    83. return this.prefix;
    84. }
    85. public void setPrefix(String prefix) {
    86. this.prefix = prefix;
    87. }
    88. public String getSuffix() {
    89. return this.suffix;
    90. }
    91. public void setSuffix(String suffix) {
    92. this.suffix = suffix;
    93. }
    94. public String getMode() {
    95. return this.mode;
    96. }
    97. public void setMode(String mode) {
    98. this.mode = mode;
    99. }
    100. public Charset getEncoding() {
    101. return this.encoding;
    102. }
    103. public void setEncoding(Charset encoding) {
    104. this.encoding = encoding;
    105. }
    106. public boolean isCache() {
    107. return this.cache;
    108. }
    109. public void setCache(boolean cache) {
    110. this.cache = cache;
    111. }
    112. public Integer getTemplateResolverOrder() {
    113. return this.templateResolverOrder;
    114. }
    115. public void setTemplateResolverOrder(Integer templateResolverOrder) {
    116. this.templateResolverOrder = templateResolverOrder;
    117. }
    118. public String[] getExcludedViewNames() {
    119. return this.excludedViewNames;
    120. }
    121. public void setExcludedViewNames(String[] excludedViewNames) {
    122. this.excludedViewNames = excludedViewNames;
    123. }
    124. public String[] getViewNames() {
    125. return this.viewNames;
    126. }
    127. public void setViewNames(String[] viewNames) {
    128. this.viewNames = viewNames;
    129. }
    130. public boolean isEnableSpringElCompiler() {
    131. return this.enableSpringElCompiler;
    132. }
    133. public void setEnableSpringElCompiler(boolean enableSpringElCompiler) {
    134. this.enableSpringElCompiler = enableSpringElCompiler;
    135. }
    136. public boolean isRenderHiddenMarkersBeforeCheckboxes() {
    137. return this.renderHiddenMarkersBeforeCheckboxes;
    138. }
    139. public void setRenderHiddenMarkersBeforeCheckboxes(boolean renderHiddenMarkersBeforeCheckboxes) {
    140. this.renderHiddenMarkersBeforeCheckboxes = renderHiddenMarkersBeforeCheckboxes;
    141. }
    142. public Reactive getReactive() {
    143. return this.reactive;
    144. }
    145. public Servlet getServlet() {
    146. return this.servlet;
    147. }
    148. public static class Servlet {
    149. /**
    150. * Content-Type value written to HTTP responses.
    151. */
    152. private MimeType contentType = MimeType.valueOf("text/html");
    153. /**
    154. * Whether Thymeleaf should start writing partial output as soon as possible or
    155. * buffer until template processing is finished.
    156. */
    157. private boolean producePartialOutputWhileProcessing = true;
    158. public MimeType getContentType() {
    159. return this.contentType;
    160. }
    161. public void setContentType(MimeType contentType) {
    162. this.contentType = contentType;
    163. }
    164. public boolean isProducePartialOutputWhileProcessing() {
    165. return this.producePartialOutputWhileProcessing;
    166. }
    167. public void setProducePartialOutputWhileProcessing(boolean producePartialOutputWhileProcessing) {
    168. this.producePartialOutputWhileProcessing = producePartialOutputWhileProcessing;
    169. }
    170. }
    171. public static class Reactive {
    172. /**
    173. * Maximum size of data buffers used for writing to the response. Templates will
    174. * execute in CHUNKED mode by default if this is set.
    175. */
    176. private DataSize maxChunkSize = DataSize.ofBytes(0);
    177. /**
    178. * Media types supported by the view technology.
    179. */
    180. private List mediaTypes;
    181. /**
    182. * Comma-separated list of view names (patterns allowed) that should be executed
    183. * in FULL mode even if a max chunk size is set.
    184. */
    185. private String[] fullModeViewNames;
    186. /**
    187. * Comma-separated list of view names (patterns allowed) that should be the only
    188. * ones executed in CHUNKED mode when a max chunk size is set.
    189. */
    190. private String[] chunkedModeViewNames;
    191. public List getMediaTypes() {
    192. return this.mediaTypes;
    193. }
    194. public void setMediaTypes(List mediaTypes) {
    195. this.mediaTypes = mediaTypes;
    196. }
    197. public DataSize getMaxChunkSize() {
    198. return this.maxChunkSize;
    199. }
    200. public void setMaxChunkSize(DataSize maxChunkSize) {
    201. this.maxChunkSize = maxChunkSize;
    202. }
    203. public String[] getFullModeViewNames() {
    204. return this.fullModeViewNames;
    205. }
    206. public void setFullModeViewNames(String[] fullModeViewNames) {
    207. this.fullModeViewNames = fullModeViewNames;
    208. }
    209. public String[] getChunkedModeViewNames() {
    210. return this.chunkedModeViewNames;
    211. }
    212. public void setChunkedModeViewNames(String[] chunkedModeViewNames) {
    213. this.chunkedModeViewNames = chunkedModeViewNames;
    214. }
    215. }
    216. }

    3.使用

    导入对应的依赖,将html放在templates目录下即可

    1. //在templates目录下的所有页面,只能通过controller来跳转
    2. //需要模板引擎的支持:thymeleaf
    3. @Controller
    4. public class IndexController {
    5. @RequestMapping("/test")
    6. public String index(){
    7. return "test";
    8. }
    9. }

    运行结果

             

    五、Thymeleaf语法

    1.thymeleaf 中文文档

    关于我们 · Using Thymeleaf 译文 (gitbooks.io)

    2.thymeleaf 属性优先级

    3.Thymeleaf标准表达式语法(Thymeleaf Standard Expression syntax)。

    我们已经见过了两种用这种语法表达的合理的属性值:消息和变量表达式:

    1. <p th:utext="#{home.welcome}">Welcome to our grocery store!p>
    2. <p>Today is: <span th:text="${today}">25 August 2022span>p>

    但是表达式的种类远不止这些,而且关于我们已知的这两种还有一些更有趣的细节需要了解。首先,让我们快速的看一下标准表达式的功能。

    • 简单表达式 Simple Expressions:
      • 变量表达式 Variable Expressions: ${...}
      • 选中变量表达式 Selection Variable Expressions: *{...}
      • 消息表达式 Message Expressions: #{...}
      • 连接URL表达式 Link URL Expressions: @{...}
      • 片段表达式 Fragment Expressions: ~{...}
    • 常量 Literals
      • 文本常量 Text literals: 'one text''Another one!',…
      • 数字常量 Number literals: 0343.012.3,…
      • 布尔常量 Boolean literals: truefalse
      • 空常量 Null literal: null
      • 常符号 Literal tokens: onesometextmain,…
    • 文本操作 Text operations:
      • 字符串连接 String concatenation: +
      • 常量替换 Literal substitutions: |The name is ${name}|
    • 算数操作 Arithmetic operations:
      • Binary operators: +-*/%
      • Minus sign (unary operator): -
    • 布尔操作 Boolean operations:
      • 布尔操作符 Binary operators: andor
      • 布尔否定 一元操作符Boolean negation (unary operator): !not
    • 比较和相等 Comparisons and equality:
      • 比较符 Comparators: ><>=<= (gtltgele)
      • 相等符 Equality operators: ==!= (eqne)
    • 条件操作符 Conditional operators:
      • If-then: (if) ? (then)
      • If-then-else: (if) ? (then) : (else)
      • 默认值 Default: (value) ?: (defaultvalue)
    • 特殊符号 Special tokens:
      • 无操作符 No-Operation: _

    这些功能可以自由的组合和嵌套:

    'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
  • 相关阅读:
    BPMN2.0协议简介
    nginx安装和使用
    JVM性能优化案例:优化垃圾回收器的年轻代和老年代占比
    计算机毕业设计微信小程序校园辩论管理平台
    .Net依赖注入神器Scrutor(上)
    LeetCode 1161.最大层内元素和:层序遍历
    【Redis学习笔记】第二章 Redis数据类型
    JAVA计算机毕业设计员工婚恋交友平台Mybatis+源码+数据库+lw文档+系统+调试部署
    Bi-Modal Progressive Mask Attention for Fine-Grained Recognition
    JavaScript常见面试题(二)
  • 原文地址:https://blog.csdn.net/m0_52982868/article/details/126498988