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
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
        return;
    }
    addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
        if (this.servletContext != null) {
            ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
            registration.addResourceLocations(resource);
        }
    });
}
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
    addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
}
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, Consumer<ResourceHandlerRegistration> customizer) {
if (registry.hasMappingForPattern(pattern)) {
    return;
}
ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
customizer.accept(registration);
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
customizeResourceHandlerRegistration(registration);
}

二、导入静态资源

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 

/**
 * An {@link AbstractUrlHandlerMapping} for an application's welcome page. Supports both
 * static and templated files. If both a static and templated index page are available,
 * the static page is preferred.
 *
 * @author Andy Wilkinson
 * @author Bruce Brouwer
 */
final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {

	private static final Log logger = LogFactory.getLog(WelcomePageHandlerMapping.class);

	private static final List<MediaType> MEDIA_TYPES_ALL = Collections.singletonList(MediaType.ALL);

	WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
			ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
		if (welcomePage != null && "/**".equals(staticPathPattern)) {
			logger.info("Adding welcome page: " + welcomePage);
			setRootViewName("forward:index.html");
		}
		else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
			logger.info("Adding welcome page template: index");
			setRootViewName("index");
		}
	}

	private boolean welcomeTemplateExists(TemplateAvailabilityProviders templateAvailabilityProviders,
			ApplicationContext applicationContext) {
		return templateAvailabilityProviders.getProvider("index", applicationContext) != null;
	}

	private void setRootViewName(String viewName) {
		ParameterizableViewController controller = new ParameterizableViewController();
		controller.setViewName(viewName);
		setRootHandler(controller);
		setOrder(2);
	}

	@Override
	public Object getHandlerInternal(HttpServletRequest request) throws Exception {
		for (MediaType mediaType : getAcceptedMediaTypes(request)) {
			if (mediaType.includes(MediaType.TEXT_HTML)) {
				return super.getHandlerInternal(request);
			}
		}
		return null;
	}

	private List<MediaType> getAcceptedMediaTypes(HttpServletRequest request) {
		String acceptHeader = request.getHeader(HttpHeaders.ACCEPT);
		if (StringUtils.hasText(acceptHeader)) {
			return MediaType.parseMediaTypes(acceptHeader);
		}
		return MEDIA_TYPES_ALL;
	}

}

测试: 

注意:在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 

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

确认成功导入

ThymeleafProperties 源码 

@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"; //后缀必须以.html结尾

	/**
	 * Whether to check that the template exists before rendering it.
	 */
	private boolean checkTemplate = true;

	/**
	 * Whether to check that the templates location exists.
	 */
	private boolean checkTemplateLocation = true;

	/**
	 * Prefix that gets prepended to view names when building a URL.
	 */
	private String prefix = DEFAULT_PREFIX;

	/**
	 * Suffix that gets appended to view names when building a URL.
	 */
	private String suffix = DEFAULT_SUFFIX;

	/**
	 * Template mode to be applied to templates. See also Thymeleaf's TemplateMode enum.
	 */
	private String mode = "HTML";

	/**
	 * Template files encoding.
	 */
	private Charset encoding = DEFAULT_ENCODING;

	/**
	 * Whether to enable template caching.
	 */
	private boolean cache = true;

	/**
	 * Order of the template resolver in the chain. By default, the template resolver is
	 * first in the chain. Order start at 1 and should only be set if you have defined
	 * additional "TemplateResolver" beans.
	 */
	private Integer templateResolverOrder;

	/**
	 * Comma-separated list of view names (patterns allowed) that can be resolved.
	 */
	private String[] viewNames;

	/**
	 * Comma-separated list of view names (patterns allowed) that should be excluded from
	 * resolution.
	 */
	private String[] excludedViewNames;

	/**
	 * Enable the SpringEL compiler in SpringEL expressions.
	 */
	private boolean enableSpringElCompiler;

	/**
	 * Whether hidden form inputs acting as markers for checkboxes should be rendered
	 * before the checkbox element itself.
	 */
	private boolean renderHiddenMarkersBeforeCheckboxes = false;

	/**
	 * Whether to enable Thymeleaf view resolution for Web frameworks.
	 */
	private boolean enabled = true;

	private final Servlet servlet = new Servlet();

	private final Reactive reactive = new Reactive();

	public boolean isEnabled() {
		return this.enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public boolean isCheckTemplate() {
		return this.checkTemplate;
	}

	public void setCheckTemplate(boolean checkTemplate) {
		this.checkTemplate = checkTemplate;
	}

	public boolean isCheckTemplateLocation() {
		return this.checkTemplateLocation;
	}

	public void setCheckTemplateLocation(boolean checkTemplateLocation) {
		this.checkTemplateLocation = checkTemplateLocation;
	}

	public String getPrefix() {
		return this.prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	public String getSuffix() {
		return this.suffix;
	}

	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}

	public String getMode() {
		return this.mode;
	}

	public void setMode(String mode) {
		this.mode = mode;
	}

	public Charset getEncoding() {
		return this.encoding;
	}

	public void setEncoding(Charset encoding) {
		this.encoding = encoding;
	}

	public boolean isCache() {
		return this.cache;
	}

	public void setCache(boolean cache) {
		this.cache = cache;
	}

	public Integer getTemplateResolverOrder() {
		return this.templateResolverOrder;
	}

	public void setTemplateResolverOrder(Integer templateResolverOrder) {
		this.templateResolverOrder = templateResolverOrder;
	}

	public String[] getExcludedViewNames() {
		return this.excludedViewNames;
	}

	public void setExcludedViewNames(String[] excludedViewNames) {
		this.excludedViewNames = excludedViewNames;
	}

	public String[] getViewNames() {
		return this.viewNames;
	}

	public void setViewNames(String[] viewNames) {
		this.viewNames = viewNames;
	}

	public boolean isEnableSpringElCompiler() {
		return this.enableSpringElCompiler;
	}

	public void setEnableSpringElCompiler(boolean enableSpringElCompiler) {
		this.enableSpringElCompiler = enableSpringElCompiler;
	}

	public boolean isRenderHiddenMarkersBeforeCheckboxes() {
		return this.renderHiddenMarkersBeforeCheckboxes;
	}

	public void setRenderHiddenMarkersBeforeCheckboxes(boolean renderHiddenMarkersBeforeCheckboxes) {
		this.renderHiddenMarkersBeforeCheckboxes = renderHiddenMarkersBeforeCheckboxes;
	}

	public Reactive getReactive() {
		return this.reactive;
	}

	public Servlet getServlet() {
		return this.servlet;
	}

	public static class Servlet {

		/**
		 * Content-Type value written to HTTP responses.
		 */
		private MimeType contentType = MimeType.valueOf("text/html");

		/**
		 * Whether Thymeleaf should start writing partial output as soon as possible or
		 * buffer until template processing is finished.
		 */
		private boolean producePartialOutputWhileProcessing = true;

		public MimeType getContentType() {
			return this.contentType;
		}

		public void setContentType(MimeType contentType) {
			this.contentType = contentType;
		}

		public boolean isProducePartialOutputWhileProcessing() {
			return this.producePartialOutputWhileProcessing;
		}

		public void setProducePartialOutputWhileProcessing(boolean producePartialOutputWhileProcessing) {
			this.producePartialOutputWhileProcessing = producePartialOutputWhileProcessing;
		}

	}

	public static class Reactive {

		/**
		 * Maximum size of data buffers used for writing to the response. Templates will
		 * execute in CHUNKED mode by default if this is set.
		 */
		private DataSize maxChunkSize = DataSize.ofBytes(0);

		/**
		 * Media types supported by the view technology.
		 */
		private List<MediaType> mediaTypes;

		/**
		 * Comma-separated list of view names (patterns allowed) that should be executed
		 * in FULL mode even if a max chunk size is set.
		 */
		private String[] fullModeViewNames;

		/**
		 * Comma-separated list of view names (patterns allowed) that should be the only
		 * ones executed in CHUNKED mode when a max chunk size is set.
		 */
		private String[] chunkedModeViewNames;

		public List<MediaType> getMediaTypes() {
			return this.mediaTypes;
		}

		public void setMediaTypes(List<MediaType> mediaTypes) {
			this.mediaTypes = mediaTypes;
		}

		public DataSize getMaxChunkSize() {
			return this.maxChunkSize;
		}

		public void setMaxChunkSize(DataSize maxChunkSize) {
			this.maxChunkSize = maxChunkSize;
		}

		public String[] getFullModeViewNames() {
			return this.fullModeViewNames;
		}

		public void setFullModeViewNames(String[] fullModeViewNames) {
			this.fullModeViewNames = fullModeViewNames;
		}

		public String[] getChunkedModeViewNames() {
			return this.chunkedModeViewNames;
		}

		public void setChunkedModeViewNames(String[] chunkedModeViewNames) {
			this.chunkedModeViewNames = chunkedModeViewNames;
		}

	}

}

3.使用

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

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

运行结果

         

五、Thymeleaf语法

1.thymeleaf 中文文档

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

2.thymeleaf 属性优先级

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

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

<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>

<p>Today is: <span th:text="${today}">25 August 2022</span></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'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

elk-zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值