前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot之Web开发

SpringBoot之Web开发

作者头像
OY
发布2022-03-12 14:10:49
9620
发布2022-03-12 14:10:49
举报
文章被收录于专栏:OY_学习记录

一、Web 开发

自动配置原理:

xxxAutoConfiguration: 帮助我们给容器中自动配置组件; xxxProperyties: 配置类来

1、 SpringBoot 对静态资源的映射规则

代码语言:javascript
复制
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
// 可是设置和静态资源有关的参数,缓存时间等
WebMvcAuotConfiguration:
@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;
	}
}
  1. ==所有的/webjars/**,都去 classpath:/META-INF/resources/web/找资源== webjars :以 jar 包的方式引入静态资源;http://www.webjars.org/

导入依赖:

代码语言:javascript
复制
<!--引入jquery-webjar 访问的时候只需要写webjars下面的资源名称即可-->
<dependency>
	<groupId>org.webjars.bower</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

测试:localhost:8080/webjars/jquery/3.3.1/dist/jquery.js

  1. ==”/**访问当前项目的任何资源,都去(静态资源的文件夹)找映射。==
  • “classpath:/META-INF/resources/“
  • “classpath:/resources/“
  • “classpath:/static/“
  • “classpath:/public/“
  • “/“:当前项目

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

  1. ==欢迎页: 静态资源文件下的所有 index.html 页面;被”/**“映射==
  1. ==所有的 **/favicaon.ico 都是在静态资源文件下找==

2、引擎模板

jsp、velocity、Freemarker、Thymeleaf

SpringBoot 推荐的 Tymeleaf,语法更简单,功能更强大;

① 引入 thymeleaf
代码语言:javascript
复制
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
   <version>2.3.1.RELEASE</version>
</dependency>

测试

代码语言:javascript
复制
@RequestMapping(value = "/success")
    public String success(){
        return "success";
}

切换 thymeleaf 版本

代码语言:javascript
复制
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<!-- 布局功能的支持程序  thymeleaf3主程序  layout2以上版本 -->
<thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>

==启动报错==:

代码语言:javascript
复制
***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration$ThymeleafDefaultConfiguration.templateEngine(ThymeleafAutoConfiguration.java:142)

The following method did not exist:

==解决方案==:

代码语言:javascript
复制
<properties>
    <springboot-thymeleaf.version>3.0.9.RELEASE</springboot-thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
</properties>

原因分析

​ 这里用的 org.springframework.boot 下的 spring-boot-starter-thymeleaf,使用<thymeleaf.version>做标签时的可能与 org.thymeleaf 头冲突,导致包获取不正确。

② Thymeleaf 使用
代码语言:javascript
复制
@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
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";
    //

​ 只要我们把 HTML 页面的放在 classpath:/templates/, thymeleaf 就能自动渲染。

使用

  1. 导入 thymeleaf 的名称空间
代码语言:javascript
复制
<html lang="en" xmlns:th="http://www.thymeleaf.org"></html>
  1. 使用 thymeleaf 语法
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <h1>success 测试成功</h1>
    <div th:text="${hello}"></div>
  </body>
</html>
③ 语法规则
  1. th:text: 改变当前元素里面的内容。 th: 任意 html 属性;来替换原生的值。
  1. 表达式
代码语言:javascript
复制
Simple expression: (表达式语法)
	Variable Expressions:${...}: 获取变量值; OGNL;
				1)、获取对象的属性、调用方法
                2)、使用内置的基本对象:
                    # ctx: the context object.
                    #vars: the context variables.
					#locale : the context locale.
					#request : (only in Web Contexts) the HttpServletRequest object.
					#response : (only in Web Contexts) the HttpServletResponse object.
					#session : (only in Web Contexts) the HttpSession object.
					#servletContext : (only in Web Contexts) the ServletContext object.
                 ${session.foo}
				3)、内置的一些工具对象
     #execInfo : information about the template being processed.
	#messages : methods for obtaining externalized messages inside variables expressions, in the
	same way as they would be obtained using #{…} syntax.
    #uris : methods for escaping parts of URLs/URIs
	#conversions : methods for executing the configured conversion service (if any).
	#dates : methods for java.util.Date objects: formatting, component extraction, etc.
	#calendars : analogous to #dates , but for java.util.Calendar objects.
	#numbers : methods for formatting numeric objects.
	#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
	#objects : methods for objects in general.
	#bools : methods for boolean evaluation.
	#arrays : methods for arrays.
	#lists : methods for lists.
    #sets : methods for sets.
	#maps : methods for maps.
	#aggregates : methods for creating aggregates on arrays or collections.
	#ids : methods for dealing with id attributes that might be repeated (for example, as a
	result of an iteration).

    Selection Variable Expressions: *{.....}: 选择表达式:和${}在功能上是一样;
		补充: 配合 th:object="${session.user}"
    <div th:object="${session.user}">
    <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
	<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
	<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
	</div>

    Message Expressions: #{...}: 获取国际化内容
    Link URL Expressions: @{....}: 定义URL;
		@{/order/process(execId=${execId},execType='FAST')}
		Fragment Expressions: ~{...}:片段引用表达式
		<div th:insert="~{commons :: main}">...</div>
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)
Special tokens:
	No‐Operation: _

3、SpringMVC 自动配置

​ 可以参考文档:https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developingweb-applications

① Spring MVC auto-configuration

Spring Boot 自动配置好了 SpringMVC

以下是 SpringBoot 对 SpringMVC 的默认配置:==(WebMvcAutoConfiguration)==

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
    • 自动配置 ViewResource(视图解析器:根据方法的返回值得视图对象的(View), 视图对象决定如何渲染(转发?重定向?))
    • ContextNegotiatingViewResolver: 组合所有的视图解析器的;
    • ==如何定制:我们可以给自己容器中添加一个视图解析器;自动的将其组合进来;==
  • Support for serving static resources, including support for WebJars (see below). 静态资源文件夹路径,webjars
  • Static index.html support。静态首页的访问
  • Custom Favicon support (see below). favicon.ico
  • 自动注册 of Converter , GenericConverter, Formatter bean
    • Converter: 转换器;public String hello(User user): 类型转换使用 Converter
    • Formatter 格式化器: 2020.8.29 == Date;
代码语言:javascript
复制
@Bean
@ConditionalOnProperty(prefix = "spring.mvc", name = "date‐format")//在文件中配置日期格
式化的规则
public Formatter<Date> dateFormatter() {
	return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
}

==自己添加的格式化器转换器,我们只需要放在容器中即可==

  • Support for HttpMessageConverters (see below)
    • HttpMessageConverter: SpringMVC 用来转换 Http 请求和响应的 :User—json;
    • HttpMessageConverters 是从容器中确定;获取所有的 HttpMessageConverter; 给自己的容器中添加 HttpMessageConverter,只需要将自己的组件注册容器中(@Bean, @Component)
  • Automatic registration of MessageCodesResolver (see below). 定义错误的代码生成规则
  • Automatic use of a ConfigurableWebBindingInitializer bean (see below). ==我们可以配置一个 ConfigurableWebBindingInitialzer 来替换默认的:(添加到容器)==
代码语言:javascript
复制
初始化WebDataBinder;
请求数据=====JavaBean;

org.springframework.boot.autoconfigure.web 的所有的自动场景;

If you want to keep Spring Boot MVC features, and you just want to add additional ==MVC configuration==(interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter , but without @EnableWebMvc . If you wish to provide custom instances of RequestMappingHandlerMapping , RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc .

② 扩展 SpringMVC
代码语言:javascript
复制
<mvc:view-controller path="/hello" view-name="success"/>
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/hello"/>
        <bean></bean>
    </mvc:interceptor>
</mvc:interceptors>

==编写一个配置类(@Configuration),是 WebMvcConfigAdapter 类型;不能标注@EnableWebMVC==

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

注:WebMvcConfigurerAdapter该方法在 spring boot 2.0,Spring 5.0 之后,已经被废弃

代码语言:javascript
复制
// 使用WebMvcConfigurer可以来扩展SpringMVC的功能
@Configuration
public class MyMvcConfig implements WebMvcConfigurer{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // super.addViewControllers(registry);
        // 浏览器发送 /oy 请求到 success
        registry.addViewController("/oy").setViewName("success");
    }
}

测试:

原理:

代码语言:javascript
复制
1. WebMvcAutoConfiguration是SpringMVC的自动配置类
  1. 在做其他的自动配置时会导入:@Import(EnableWebMvcConfiguration.class)
代码语言:javascript
复制
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
	private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
	// 从容器中获取所有的WebmvcConfigurer
	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
		this.configurers.addWebMvcConfigurers(configurers);
		//一个参考实现;将所有的WebMvcConfigurer相关配置都来一起调用;
	@Override
	// public void addViewControllers(ViewControllerRegistry registry) {
	// for (WebMvcConfigurer delegate : this.delegates) {
	// delegate.addViewControllers(registry);
	// }
}
  1. 容器中所有的 WebMvcConfigurer 都会一起起作用
  2. 我们的配置类也会被调用; 效果:SpringMVC 的自动配置和我们的扩展配置都会起作用;
③、全面接管 SpringMVC;

SpringBoot 对 SpringMVC 的自动配置不需要了,所有都是我们自己配置;所有的 SpringMVC 的自动配置都失效了

我们需要在配置类中添加@EnableWebMvc 即可;

代码语言:javascript
复制
// 使用WebMvcConfigurer可以来扩展SpringMVC的功能
@Configuration
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
       /* super.addViewControllers(registry);*/
        // 浏览器 /oy 请求来到 success
        registry.addViewController("/oy").setViewName("success");
    }
}

原理:(为什么@EnableWebMvc 自动配置就失效了)

  1. @EnableWebMvc 的核心
代码语言:javascript
复制
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {

2.

代码语言:javascript
复制
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

3.

代码语言:javascript
复制
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,WebMvcConfigurerAdapter.class })
//容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
  1. @EnableWebMvc 将 WebMvcConfiguationSupport 组件导入进来
  2. 导入的 WebMvcConfiguration 只是 SpringMVC 最基本功能;

5、如何修改 SpringBoot 的默认设置

模式:

  1. SpringBoot 在自动配置很多组件的时候,先看容器中有没有自己配置的(@Bean、@Component)如果有就用户自己配置,如果没有,才自动配置和自己默认组合起来;
  2. 在 SpringBoot 中国会有非常多的 xxxConfigurer 帮助我们进行扩展配置
  3. 在 SpringBoot 中会有很多的 xxxCustomize 帮助我们进行定制配置

6、RestfulCRUD

配置 pom 配置文件

代码语言:javascript
复制
   <properties>
       <!-- 布局功能的支持程序  thymeleaf3主程序  layout2以上版本 -->
       <springboot-thymeleaf.version>3.0.9.RELEASE</springboot-thymeleaf.version>
       <thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
</properties>
<!--配置thymeleaf模板-->
   <dependencies>
       <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-thymeleaf</artifactId>
               <version>2.3.1.RELEASE</version>
       </dependency>
   </dependencies>
① 默认访问首页

方式一:(不推荐)

代码语言:javascript
复制
// 在Controller中配置
	@RequestMapping({"/","/index.html"})
    public String index(){
        return "index";
    }

方式二:(推荐)

代码语言:javascript
复制
// 使用WebConfigurerAdapter可以来扩展SpringMVC的功能
// 使用@EnableWebMvc 不要接管SpringMVC
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
//        super.addViewControllers(registry);
        //浏览器发送得 /oy 请求来到 success
        registry.addViewController("/oy").setViewName("success");
    }

    // 所有的webMvcConfigAdapter组件都会一起起作用
    @Bean // 将组件注册在容器
    public MyMvcConfig MyMvcConfig1(){
        MyMvcConfig config = new MyMvcConfig(){
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/index.html").setViewName("login");
            }
        };
        return config;
    }
}

【application.properties】

代码语言:javascript
复制
server.servlet.context-path=/curd

测试:

提前在 POM.xml 文件中引入 bootstrap 依赖(后面需要)

代码语言:javascript
复制
<!--引入bootstrap-->
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>4.0.0</version>
</dependency>
② 国际化
  1. 编写国际化配置文件:
  1. SpringBoot 自动配置好了管理国际化资源文件的组件(2.x 版本):
代码语言:javascript
复制
@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;
   }

1.x 版本:

代码语言:javascript
复制
@ConfigurationProperties(prefix = "spring.messages")
public class MessageSourceAutoConfiguration {
    /**
    * Comma‐separated list of basenames (essentially a fully‐qualified classpath
    * location), each following the ResourceBundle convention with relaxed support for
    * slash based locations. If it doesn't contain a package qualifier (such as
    * "org.mypackage"), it will be resolved from the classpath root.
    */
	private String basename = "messages";
	//我们的配置文件可以直接放在类路径下叫messages.properties;
	@Bean
	public MessageSource messageSource() {
	ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
	if (StringUtils.hasText(this.basename)) {
		//设置国际化资源文件的基础名(去掉语言国家代码的)
		messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
		StringUtils.trimAllWhitespace(this.basename)));
	}
    if (this.encoding != null) {
		messageSource.setDefaultEncoding(this.encoding.name());
	}
   messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale);
	messageSource.setCacheSeconds(this.cacheSeconds);
	messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat);
	return messageSource;
}
  1. application.properties 文件中配置:
代码语言:javascript
复制
#指定管理国际化资源文件
spring.messages.basename=i18n.login
  1. 去页面获取的国际化的值
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="description" content="" />
    <meta name="author" content="" />
    <title>Signin Template for Bootstrap</title>
    <!-- Bootstrap core CSS -->
    <link
      href="asserts/css/bootstrap.min.css"
      th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}"
      rel="stylesheet"
    />
    <!-- Custom styles for this template -->
    <link
      href="asserts/css/signin.css"
      th:href="@{/asserts/css/signin.css}"
      rel="stylesheet"
    />
  </head>

  <body class="text-center">
    <form class="form-signin" action="dashboard.html">
      <img
        class="mb-4"
        src="asserts/img/bootstrap-solid.svg"
        th:src="@{/asserts/img/bootstrap-solid.svg}"
        alt=""
        width="72"
        height="72"
      />
      <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">
        Please sign in
      </h1>
      <label class="sr-only" th:text="#{login.username}">Username</label>
      <input
        type="text"
        class="form-control"
        placeholder="Username"
        th:placeholder="#{login.username}"
        required=""
        autofocus=""
      />
      <label class="sr-only" th:text="#{login.password}">Password</label>
      <input
        type="password"
        class="form-control"
        placeholder="Password"
        th:placeholder="#{login.password}"
        required=""
      />
      <div class="checkbox mb-3">
        <label>
          <input type="checkbox" value="remember-me" /> [[#{login.remember}]]
        </label>
      </div>
      <button
        class="btn btn-lg btn-primary btn-block"
        type="submit"
        th:text="#{login.btn}"
      >
        Sign in
      </button>
      <p class="mt-5 mb-3 text-muted">© 2017-2018</p>
      <a class="btn btn-sm">中文</a>
      <a class="btn btn-sm">English</a>
    </form>
  </body>
</html>

测试:(更改浏览器语言)

原理:

国际化 Locale(区域信息对象); LocaleResolver(获取区域信息对象)

代码语言:javascript
复制
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
	if (this.mvcProperties
		.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
		return new FixedLocaleResolver(this.mvcProperties.getLocale());
	}
    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
	localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
	return localeResolver;
}
默认的就是根据请求头带来的区域信息Localhost进行国际化
  1. 点击切换国际化

【MyLocaleResolver.calss】

代码语言:javascript
复制
// 可以在连接上携带区域的信息
public class MyLocaleResolver implements LocaleResolver{
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        String l = httpServletRequest.getParameter("l");
        Locale locale = Locale.getDefault();
        if(!StringUtils.isEmpty("_")){
            String[] split = l.split("_");
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

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

    }
}

【MyMvcConfig.class】

代码语言:javascript
复制
@Bean
public LocaleResolver localeResolver(){
    return new MyLocaleResolver();
}

【login.html】

代码语言:javascript
复制
<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>
③ 登录

开发期间模板的引擎页面修改以后,要实时生效

  1. 禁用模板引擎的缓存
代码语言:javascript
复制
# 禁用缓存
spring.thymeleaf.cache=false
  1. 页面修改完成完成以后 ctrl +f9 : 重新编译;

【MyLocaleResolver.class】

代码语言:javascript
复制
public class MyLocaleResolver implements LocaleResolver{
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        String l = httpServletRequest.getParameter("l");
        Locale locale = Locale.getDefault();
        if(!StringUtils.isEmpty(l)){
            String[] split = l.split("_");
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

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

    }
}

【LonginController.class】

代码语言:javascript
复制
@Controller
public class LonginController {

    @PostMapping(value = "/user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String passsword, Map<String , Object> map, HttpSession session){
        if(!StringUtils.isEmpty(username) && "123456".equals(passsword)){
            // 登陆成功,防止表单重复提交,可以重定向到主页
            session.setAttribute("loginUser",username);
            return "redirect:/main.html";
        }else{
            // 登录失败
            map.put("msg","用户名密码错误");
            return "login";
        }
    }
}

【MyMvcConfig.class】

代码语言:javascript
复制
@Bean
   public MyMvcConfig MyMvcConfig1(){
       MyMvcConfig config = new MyMvcConfig(){
           @Override
           public void addViewControllers(ViewControllerRegistry registry) {
               registry.addViewController("/").setViewName("login");
               registry.addViewController("/index.html").setViewName("login");
               registry.addViewController("/main.html").setViewName("dashboard");
           }
       };
       return config;
   }

登录错误提示消息

【login.html】

代码语言:javascript
复制
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
④ 拦截器进行登陆检查

拦截器

代码语言:javascript
复制
/**
*@Description 登录检查
*@Author OY
*@Date 2020/9/3
*@Time 16:07
*/
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 {

    }
}

注册拦截器:【MyMvcConfig.class】

注: 拦截器必须配置不拦截 css 样式,不然页面的 css 样式会失效

代码语言:javascript
复制
// 所有的webMvcConfig组件都会一起起作用
    @Bean // 将组件注册在容器
    public MyMvcConfig MyMvcConfig1(){
        MyMvcConfig config = new MyMvcConfig(){
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/index.html").setViewName("login");
                registry.addViewController("/main.html").setViewName("dashboard");
            }

            // 注册拦截器
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                // 静态资源: *.css , *.js
                // SpringBoot已经做好了静态资源映射
/*                registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/")
                            .excludePathPatterns("/index.html","/","/user/login","/asset/**","/webjars/**");*/

                registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
                        .excludePathPatterns("/index.html",
                                "/",
                                "/user/login","/static/**", "/webjars/**");
//
            }
        };
        return config;
    }
⑤ CRUD-员工列表

实验要求:

  1. RestfulCURD: CURD 满足 Rest 风格

URL:/ 资源名称 / 资源标识 HTTP 请求的方式区分对资源 CRUD 操作

普通 CURD(uri 来区分操作)

RestfulCRUD

查询

getEmp

emp—GET

添加

addEmp?xxx

emp—POST

修改

updateEmp?id=xxx&xxx=xx

emp/{id}—PUT

删除

deleteEmp?id=1

emp/{id}—DELETE

  1. 实验的请求架构

实验功能

请求 URL

请求方式

查询所有员工

emps

GET

查询某个员工(来到修改页面)

emp/1

GET

来到添加页面

emp

GET

添加员工

emps

POST

来到修改页面(查出员工进行信息回显)

emp/1

GET

修改员工

emp

PUT

删除员工

emp/1

DELETE

  1. 员工列表

thymeleaf 公共页面元素的抽取

1、抽取公共片段 <div th:fragment=”copy”> © 2011 The Good Thymes Virtual Grocery </div> 2、引入公共片段 <div th:insert=”~{footer:: copy}”>

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Web 开发
    • 1、 SpringBoot 对静态资源的映射规则
      • 2、引擎模板
        • 3、SpringMVC 自动配置
          • 5、如何修改 SpringBoot 的默认设置
            • 6、RestfulCRUD
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档