2019-02-14到2019-02-29

2019-02-28  本文已影响0人  织雾呀

我可没有断更

模板引擎

jsp freemark thymeleaf
SpringBoot提供的thymeleaf模板引擎
语法很简单,功能很强大
下面这段代码路径为:


image
@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";

语法:
只要我们把html页面放在classpath:/templates/,thymeleaf就能自动渲染
语法使用

1.th:text  改变当前元素中的文本内容
    th:任意html属性:来代替原生属性
    

image

表达式语法:

Simple expressions:
Variable Expressions: ${...}
Selection Variable Expressions: *{...}
Message Expressions: #{...}
Link URL Expressions: @{...}
Fragment Expressions: ~{...}
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:
Page 17 of 106No-Operation: _

例如循环:

<h4 th:text="${user}" th:each="user:${user}"></h4>
<span th:each="user:${user}">[[${user}]]</span>

SpringMVC自动配置

官网的解释


image

27.1.1 Spring MVC Auto-configuration
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
The auto-configuration adds the following features on top of Spring’s defaults:
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
<font color="green">视图解析器:根据方法的返回值得到视图对象(view)是由视图对象决定如何渲染视图,重定向或者转发
ContentNegotiatingViewResolver:组合所有的视图解析器
如何定制视图:使用@bean给容器添加一个自定义的视图解析器;ContentNegotiatingViewResolver会自动将其组合进来 </font>
Support for serving static resources, including support for WebJars (covered later in this document)).
<font color="green">静态资源文件夹路径是webjars</font>

Automatic registration of Converter, GenericConverter, and Formatter beans.
Support for HttpMessageConverters (covered later in this document).
Automatic registration of MessageCodesResolver (covered later in this document).
Static index.html support.<font color="green">静态访问首页</font>
Custom Favicon support (covered later in this document).
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.


如何修改Spring Boot的默认配置
: 1、Spring Boot在自动配置很多组件的时候,先看一下容器中有没有用户自己配置的(@Bean@component),如果有就用用户配置的,如果没有就使用默认配置
如果有多个组件可以有多个(viewresolver)将用户配置和自己的配置组合进来
2、在springboot中会有很多的xxxconfigraution帮助我们进行拓展
3、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制


SpringBoot国际化

1、新建properties文件


image

2、Spring Boot自动配置好了管理国际化

public MessageSourceAutoConfiguration() {
}

@Bean
@ConfigurationProperties(
    prefix = "spring.messages"
)

application.properties/yml进行配置

spring.messages.basename=i18n.login

3、获取页面的值(模板引擎thymeleaf)

效果根据浏览器的语言信息切换国际化。
点中英文进行切换国际化的原理:
: 国际化locale(区域信息对象):localeResolver
SpringBoot在类WebMvcAutoConfiguration中配置了方法如下

public LocaleResolver localeResolver() {
    if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
        return new FixedLocaleResolver(this.mvcProperties.getLocale());
    } else {
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
        return localeResolver;
    }
}

默认的就是根据请求头带来的区域信息后去locale进行国际化

页面信息:

<a th:href="@{/login.html(l='zh_CN')}">中文</a>
<a th:href="@{/login.html(l='en_US')}">English</a>

新建一个类继承LocaleResolver

public class MylocaleResolver implements LocaleResolver {

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String l = request.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) {}
}

然后在被@Configuration修饰的类中进行注入

@Bean
public LocaleResolver localeResolver(){
    System.out.println("被注入");
    return new MylocaleResolver();
}

之后在页面点击链接就可以实现对应的效果了


image

登录:
: 禁用模板引擎:

spring.thymeleaf.cache=false

页面修改之后Ctrl+f9;重新编译
错误消息提示:

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

防止表单重复提交,可以让请求重定向到主页


IDEA设置热部署

原文
maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

IDEA设置


image

然后 Shift+Ctrl+Alt+/,选择Registry


image
ok了,重启一下项目,然后改一下类里面的内容,IDEA就会自动去make了。

<font color="red">补充:</font>

以上内容是网上大部分文章写的步骤,那发现并非一定实现(似乎和spring boot的版本有关系)。如果按照以上流程配置后

修改Html后ctrl+s 内容依然没变,application.yml加上以下配置即可

spring:
  devtools:
      restart:
        #需要实时更新的目录
        additional-paths: resources/**,static/**,templates/**

SpringBoot拦截器

新建类实现接口HandlerInterceptor,然后添加对应的方法

public class LoginHandlerInterceptor implements HandlerInterceptor {

    /**
     * 目标执行之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @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("/").forward(request,response);
        }else{
            //已登录,放行请求
            return true;
        }
        return false;
    }

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

    }
}

再在配置类中进行配置

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/index/**");
    }
}

就可以了哦


CRUD员工列表

要求
1.restfulCRUD:CRUD要满足rest风格
: URI:资源名称/资源标识 http请求方式区分CRUD的操作


普通的CRUD RESTFUL风格的CRUD
查询 getEmp emp--GET
添加 addEmp?xxx emp--POST
修改 updateEmp?id=xxx emp--PUT
删除 deleteEmp?id=xxx emp--DELETE

2.请求框架


请求URL 请求方式
查询所有员工 emps GET
查询单个员工 emp/1 GET
来到添加页面 emp GET
添加页面 emp POST
来到修改页面(查询员工进行信息回显) emp/1 GET
修改员工 emp PUT
删除员工 emp/1 DELETE

抽取公共片段


配置嵌套式Servlet容器

SpringBoot2中已经做了改动,文章:聊聊springboot2的embeded container的配置改动

: SpringBoot默认的是Tomcat作为嵌入式servlet
问题:
: 1、如何定制和修改Servlet容器的相关配置
修改Servlet有关的配置

#进行配置
server.xxx=xxx
server.port=端口号
修改tomcat的配置
server.Tomcat.xxx = 修改Tomcat的配置

编写嵌入式Servlet容器的定制器;主要作用就是修改servlet的配置,下面的是SpringBoot2的方法,在配置类中进行编写

@Configuration
public class MyMvcConfig implements WebMvcConfigurer ,WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        ((TomcatServletWebServerFactory)factory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector connector) {
//                Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
//                protocol.setMaxConnections(200);
//                protocol.setMaxThreads(200);
//                protocol.setSelectorTimeout(3000);
//                protocol.setSessionTimeout(3000);
//                protocol.setConnectionTimeout(3000);
                connector.setPort(8085);
            }
        });
    }
}

注册Servlet的三大组件
servlet
filter
Listener
由于SpringBoot是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件
ServletRegistrationBean
FilterRegistrationBean
ServletListenerRegistrationBean
在注册三大组件的时候用以下方式
例:filter

public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello MyServlet");
    }
}

配置类:

@Configuration
public class MyServletConfig implements WebMvcConfigurer {
    @Bean
    public ServletRegistrationBean myServlet(){
        ServletRegistrationBean servletRegistrationBean = new
                ServletRegistrationBean(new MyServlet(),"/myservlet");
        return servletRegistrationBean;
    }
}

页面效果:


image

过滤器:

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter process...");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

配置类进行注册:



2、Spring Boot能不能支持其他的Servlet容器
jetty(长连接)
undertow(不支持jsp)
切换方法:
更换pom.xml文件

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jetty -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-undertow -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>


使用外置的servlet容器

: 嵌入式的servlet:把应用打成jar包
优点:简单,便携
缺点:不支持jsp(工作)

解决办法:
: 配置一个外置的servlet容器:外面安装一个tomcat应用war包的方式打包

1、创建一个war包项目(使用IDEA创建目录结构)
2、将嵌入式的tomcat指定为provided

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

3、必须编写一个SpringBootServletInitializer的子类,并调用configure方法

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringBootWarApplication.class);
    }
}

4、启动服务器就可以使用了


IDEA配置springboot的外置servlet容器

新建springboot项目,配置生成webapp目录


image
image

外置tomcat配置的端口号不能和springBoot配置的端口重复!


SpringBoot与Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

image

docker的安装

查看centos版本
uname -r
升级软件包及内核
yum update
安装docker
yum install docker
启动docker
systemctl start docker
将docker设为开机启动
systemctl enable docker
停止docker
systemctl stop docker

docker核心概念

: docker主机(Host):安装了docker程序的机器(Docker直接安装在操作系统之上)
docker客户端(Client):连接docker主机及进行操作(mysql)
docker仓库:docker仓库用来保存镜像,可以理解为代码控制中的代码仓库。
docker镜像:软件打包好的镜像放到仓库中让别人使用
docker容器(Container):镜像启动后的实例称为一个容器。容器是独立运行的,一个或一组。

使用docker

: 1、安装Docker
2、去docker仓库找到软件相应的镜像
3、使用Docker运行镜像,这个镜像就会生成一个docker容器
4、对镜像的启动或者停止就是对软件的启动或停止。

安装Docker

: 1、安装linux系统
2、在linux上安装Docker


SpringBoot原理

几个重要的事件回调机制
: 执行ApplicationContextInitializer,initialize()
监听器SpringApplicationRunListener回调contextPrepared
加载主配置类定义信息
监听器SpringApplicationRunListener回调contextLoaded

启动流程:
1、创建一个SpringApplication对象
: 判断当前应用是否是web应用
从类路径下查找META-INF/spring.factories配置所有的applicationContextInitialize,然后保存起来

public void setListeners(Collection<? extends ApplicationListener<?>> listeners) {
    this.listeners = new ArrayList();
    this.listeners.addAll(listeners);
}

从类路径下查找META-INF/spring.factories配置所有的applicatonListeners

private Class<?> deduceMainApplicationClass() {
    try {
        StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();
        StackTraceElement[] var2 = stackTrace;
        int var3 = stackTrace.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            StackTraceElement stackTraceElement = var2[var4];
            if ("main".equals(stackTraceElement.getMethodName())) {
                return Class.forName(stackTraceElement.getClassName());
            }
        }
    } catch (ClassNotFoundException var6) {
        ;
    }

    return null;
}

从多个主配置类中找到有main方法的主配置类

2、运行run方法
: 获取SpringApplicationRunListeners从类路径下MATE-INF/spring.factories

SpringApplicationRunListeners listeners = this.getRunListeners(args);
//回调SpringApplicationRunListeners.starting()方法
listeners.starting();

封装命令参数

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

准备环境

ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            //创建applicationcontext,决定创建web的ioc还是普通的ioc
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            //准备上下文环境,将enviroment保存到ioc中,而且applicationInitizer
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            //扫描创建加载所有的组件的地方
            this.refreshContext(context);
            //applicatonRunner先回调,commandLinerRunner再回调
            this.afterRefresh(context, applicationArguments);
            
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

启动原理:

SpringApplication.run(主程序类)
new SpringApplication(主程序类)
: 判断是否web应用
加载并保存所有的ApplicationContextInitializer(META-INF/spring.factories)
加载并保存所有的ApplicationListener
获取到主程序类

run()
: 回调所有的SpringApplicationRunListener(META-INF/spring.factories)的staring
获取ApplicationArguments
准备环境&回调所有的监听器(SpringApplicationRunListener)的environmentPrepared
打印banner信息
创建ioc容器对象(
AnnotationConfigEmbeddedWebApplicationContext(web环境容器)
AnnotationConfigApplicationContext(普通环境容器)

上一篇下一篇

猜你喜欢

热点阅读