Java打怪之路---SpringBoot与Web开发

(一)简介

使用SpringBoot;

1)、创建SpringBoot应用,选中我们需要的模块;

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

3)、自己编写业务代码;

自动配置原理?

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

xxxxAutoConfiguration:帮我们给容器中自动配置组件;
xxxxProperties:配置类来封装配置文件的内容;

(二)SpringBoot对静态资源的映射规则

这里解决的问题是我的前端页面的代码应该放到哪里

所有的对webMvc的自动配置在WebMvcAuotConfiguration这个类下

     protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    
    
            super.addResourceHandlers(registry);
            if (!this.resourceProperties.isAddMappings()) {
    
    
                logger.debug("Default resource handling disabled");
            } else {
    
    
                ServletContext servletContext = this.getServletContext();
                this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
    
    
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (servletContext != null) {
    
    
                        registration.addResourceLocations(new Resource[]{
    
    new ServletContextResource(servletContext, "/")});
                    }

                });
            }
        }
webjar:以jar包的方式引入静态资源

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

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

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

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

在这里插入图片描述我这里想要访问静态资源的Chart.min.js
启动服务后,在地址栏输入http://localhost:8080/asserts/js/Chart.min.js既可以访问。

3、欢迎页; 静态资源文件夹下的所有index.html页面;被"/**"映射;

        @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;
        }

这啥意思呢?就是他会去找index页面当为首页
首先在resource下创建public目录,之后再public目录下新建index.html
直接输入http://localhost:8080/就可以访问。

4、所有的 **/favicon.ico 都是在静态资源文件下找;

这里就是改变最左端的图标。
在这里插入图片描述

(三)模板引擎

SpringBoot推荐的Thymeleaf;

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

1、引入thymeleaf;

导入相关的包

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
          	2.1.6
		</dependency>
切换thymeleaf版本
<properties>
		<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
		<!-- 布局功能的支持程序  thymeleaf3主程序  layout2以上版本 -->
		<!-- thymeleaf2   layout1-->
		<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
  </properties>

2、Thymeleaf使用和语法

2.1Thymeleaf如何使用呢?很简单

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

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
    
    

	private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");

	private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");

	public static final String DEFAULT_PREFIX = "classpath:/templates/";

	public static final String DEFAULT_SUFFIX = ".html";
  	//

使用:

1、导入thymeleaf的名称空间

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

实现步骤

  1. 在resource目录下创建templates目录
  2. 在templates目录下创建success.html
  3. 在controller中编写success
    @RequestMapping("success")
    public String success(Map<String,Object> map){
    
    
        map.put("hello","你好");
        return "success";

    }
  1. 在页面输入localhost:8080/success访问

实现过程中的问题:

  1. Thymeleaf导入失败,或者报错。解决办法参考https://blog.csdn.net/weixin_44664095/article/details/103616670这篇博文
  2. controller中最上面的注解是@Controller,而不是@RestController。写错了就访问不到。

2.2语法规则

  1. th:text:改变当前元素里面的文本内容

  2. 语法有很多,眼花缭乱,下面实现几个功能抛砖引玉
    实现功能:

//取值
<div th:text="${hello}">这是显示欢迎信息</div>
<hr/>
//转义取值
<div th:utext="${hello}"></div>
<hr/>
<取遍历值>
<div th:text="user" th:each="user:${users}"></div>
<h4>
    <span th:each="users"> [[${
    
    user}]]</span>

</h4>

(四)springMvc自动配置原理

4.1自动配置

这里还是很复杂,等看完springMVC再过来了解(p32)

4.2SpringMVC自动扩展

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

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

//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@EnableWebMvc
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    
    

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    
    
       // super.addViewControllers(registry);
        //浏览器发送 /atguigu 请求来到 success
        registry.addViewController("/atguigu").setViewName("success");
    }
}

原理:

为什么@EnableWebMvc自动配置就失效了;

1)@EnableWebMvc的核心

@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
    
    

2)、

@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
    
    

3)、

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

4)、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来;

5)、导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;

(五)CRUD实现

5.1默认访问页面

我们将程序运行之后,首先访问的是肯定是个登录页面。那么如何实现呢?
有两种实现方法:

  1. 在contorller中添加映射
    通过localhost:8080或者localhost:8080/index进行访问
public class HelloWorldController {
    
    
    //在controller中采用映射来访问首页,但这样写每一个页面都要在controller中添加,所以在config中改变
    @RequestMapping({
    
    "/","index.html"})
    public String index(){
    
    
        return "index";
    }
  1. 编写配置文件,使用mvc的方式进行重新配置
    创建config来进行编写相关的配置文件
    在这里插入图片描述
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    
    

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

5.2国际化的实现

在登录页面,我想既有中文登录页面,也有英文登录页面
实现步骤

  1. 编写国际化配置文件
    在reosorce目录下面创建i18n目录
    创建三个配置文件:这三个文件的意思分别是,默认、英文、中文页面时显示什么。
    如果发现中文显示乱码,进入setting中的FileEncoding中将转为ascii码的选项选上。

在这里插入图片描述

  1. 上面是通过浏览器语言设置来切换国际化,接下来我们实现点击一个中文与英文的按钮来切换国际化
    通过浏览器语言设置来切换国际化的原理
    在webMvcAutoConfiguration中有一个默认的区域信息解析器。如果我们自己没有配置区域信息解析器,默认的就是根据请求头带来的区域信息获取locale进行国际化。
    现在我们想要使用自己的区域信息解析器。
 @Bean
        @ConditionalOnMissingBean(
            name = {
    
    "localeResolver"}
        )
        public LocaleResolver localeResolver() {
    
    
            if (this.webProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.WebProperties.LocaleResolver.FIXED) {
    
    
                return new FixedLocaleResolver(this.webProperties.getLocale());
            } else if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
    
    
                return new FixedLocaleResolver(this.mvcProperties.getLocale());
            } else {
    
    
                AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
                Locale locale = this.webProperties.getLocale() != null ? this.webProperties.getLocale() : this.mvcProperties.getLocale();
                localeResolver.setDefaultLocale(locale);
                return localeResolver;
            }
        }

  1. 上面讲完原理,现在来构造区域信息解析器
    首先创建一个component包,这个包下面创建MylocaleResolver类
    流程:
    首先从页面获取一个l值,就是是英文还是中文http://localhost:8080/index.html?l=en_US
    如果值非空(l=en_US),那么就将其按照_分割
    最终返回区域信息
package com.sgyj.springboot.component;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

//在连接上携带居于信息

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

    }
}

编写时遇到的问题
在编写时,遇到指针为空异常。

java.lang.NullPointerException: null
	at com.sgyj.springboot.component.MyLocaleResolver.resolveLocale(MyLocaleResolver.java:18) ~[classes/:na]

检查之后发现,是MyLocalResolver中判断字符串是否为空的参数写成了"l",正确写法应该是l

5.3登录页面

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

1)、禁用模板引擎的缓存

# 禁用缓存
spring.thymeleaf.cache=false 

2)、页面修改完成以后ctrl+f9:重新编译;

登陆错误消息的显示

<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>

4)、拦截器进行登陆检查

拦截器


/**
 * 登陆检查,
 */
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 {
    
    

    }
}

注册拦截器

  //所有的WebMvcConfigurerAdapter组件都会一起起作用
    @Bean //将组件注册在容器
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
    
    
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
    
    
            @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) {
    
    
                //super.addInterceptors(registry);
                //静态资源;  *.css , *.js
                //SpringBoot已经做好了静态资源映射
                registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
                        .excludePathPatterns("/index.html","/","/user/login");
            }
        };
        return adapter;
    }

学了三天的springboot,了解了springboot的一些基本配置,自动配置原理等。在实际进行开发的过程中,发现许多基础知识完全没接触过。比如登录过程中的cookie,session等内容,还有转发重定向等知识的忘记。Spring中的注解机制,springMVC基本就没了解过原理。

其实学这几天的springboot,我并不是想要真正的彻底搞懂他,就是想检验一下自己知识的广度。现在已经检验出来了。接下来就是重回java基础,javaweb,SSM框架。
雄关漫道真如铁,而今迈步从头越。继续努力吧!

猜你喜欢

转载自blog.csdn.net/weixin_44020747/article/details/116789528