springboot入门及整合web开发----F01

Spring Boot入门与简介

image.png

与时俱进是每一个程序员都应该有的意识,当一个Java程序员在当代步遍布的时候,你就行该想到我能多学点什么。可观的是后端的框架是稳定的,它们能够维持更久的时间在应用中,而不用担心技术的更新换代。但是类似SSH,SSM这些框架已经太久了,人们迫不及待地想使用更为优雅而又简便的框架来代替,所以SpringBoot运应而生。

Spring Boot是Spring家族中的一个全新的框架,它用来简化Spring应用程序的创建和开发过程。采用SpringBoot可以非常容易和快速的构建基于Spring框架的应用程序,它让编码变简单,配置变简单,部署变简单,监控变简单。正因为Spring Boot能够化繁为简,让开发变得极其快捷,所以在业界备受关注。目前Spring Boot在国内的关注趋势也日渐超过Spring。

学习条件

SpringBoot框架是应用在Spring Framework框架的基础上,对Spring Framework框架的进行优化和升级成为了新的框架。既SpringBoot是构建在SpringFramework框架的基础之上,所以想要学好SpringBoot-那么你肯定要掌SpringFramework。

介绍

1.Spring Boot****概述

Spring框架功能很强大,但是就算是一个很简单的项目,我们也要配置很多东西。因此就有了Spring Boot框架,它的作用很简单,就是帮我们自动配置。Spring Boot框架的核心就是自动配置,只要存在相应的jar包, Spring就帮我们自动配置。如果默认配置不能满足需求,我们还可以替换掉自动配置类,使用我们自己的配置。

Spring Boot不是对Spring的增强,而是一个快速使用Spring进行开发的框架。Spring Boot 旨在帮助开发者快速搭建 Spring 框架

image.png

使用Spring Boot可以很容易创建一个独立运行(运行jar,内嵌servlet容器)、准生产级的基于Spring框架的项目,使用Spring Boot我们可以不用甚至只需要很少的Spring配置。另外,Spring Boot还集成了嵌入式的Web服务器,系统监控等很多有用的功能,让我们快速构建企业级应用程序。

image.png

微服务是未来发展的趋势,Spring Boot 是项目微服务化发展的基石。

image.png

以上观点也是我们为什么要学习SpringBoot的关键点。

2.Spring Boot****核心功能

2.1独立运行的Spring项目

spring Boot可以以jar包形式直接运行,如 java -jar xxx.jar 优点是:节省服务器资源

2.2内嵌Tomcat和Jetty容器

Spring Boot可以选择内嵌Tomcat,Jetty,这样我们无须以war包形式部署项目。

2.3提供一个starter POMs来简化Maven配置

例如引入spring-boot-starter-web时会自动引入

image.png

spring-boot-starter-parent是一个特殊Start,它用来提供相关的Maven依赖项,使用它之后,常用的包依赖可以省去version标签。

2.4自动配置****Spring

Spring Boot会根据在类路径中的jar包,类,为jar包里的类自动配置Bean,这样会极大减少我们要使用的配置。当然SpringBoot只考虑了大部分开发场景,并不是所有的场景,如果在实际的开发中我们需要自动配置Bean,而Spring Boot不能满足,则可以自定义自动配置。

2.5准生产的应用监控

Spring Boot提供基于http,ssh,telnet对运行时的项目进行监控。

2.6无代码生成和****xml****配置

Spring Boot大量使用spring4.x提供的注解新特性来实现无代码生成和xml配置。 spring4.x提倡使用Java配置和注解配置组合,而Spring Boot不需要任何xml配置即可实现spring的所有配置。

综上我们可以得出:Spring Boot让开发变得简单,让部署变得简单,让监控变得简单,让配置变得更简单。

3.快速入门

Spring Boot 2.1.6.RELEASE需要Java 8,并且与Java 11兼容(包括在内)。

还需要Spring Framework 5.1.8.RELEASE或更高版本。

3.1第一个 Spring Boot 项目

创建项目

image.png
image.png

编写 pom.xml

根据官网 Spring Boot 文档提示从 spring-boot-starter-parent 项目继承并向一个或多个 Starters 声明依赖项。Spring starter 是 Spring Boot 的核心,可以理解为一个可拔插式的插件,例如,你想使用Reids插件,那么可以使用 spring-boot-starter-redis;如果想使用MongoDB,可以使用 spring-boot-starter-data-mongodb。

<!--引入springboot的父类依赖-->
 <!-- 继承 springboot parent -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
  </parent>
  <!-- web 组件 -->
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>

HelloWorld

编写HelloWorldController.java

/**
 * 第一个springboot项目
 */
//该注解表示,该类下每个方法返回JSON数据
@RestController
// 表示所扫描到的服务
@EnableAutoConfiguration
public class HelloWorldController {

    @RequestMapping("/hello")
    public String hello(){
        return "Hello World!";
    }

    @RequestMapping("/getMap")
    public  Map<String,String> getMap(){
        Map<String,String> map =new HashMap<>();
        map.put("code","200");
        map.put("message","success");
        return  map;
    }

    public static void main(String[] args) {
        SpringApplication.run(HelloWorldController.class,args);
    }

}


结果如下

image.png

3.2Spring Boot 第二种启动方式

项目中肯定不止一个 Controller,我们当然希望项目启动时将所有的 Controller 全部加载进来,这种情况又该如何配置呢?比如此时有两个 Controller,都需要被执行。

HelloWorldController.java

/**
 * 第一个springboot项目
 */
//该注解表示,该类下每个方法返回JSON数据
@RestController
public class HelloWorldController {

    @RequestMapping("/hello")
    public String hello(){
        return "Hello World!";
    }

    @RequestMapping("/getMap")
    public  Map<String,String> getMap(){
        Map<String,String> map =new HashMap<>();
        map.put("code","200");
        map.put("message","success");
        return  map;
    }


}

另外一个IndexController.java

/**
 * 有两个controller
 */
@RestController
public class IndexController {
    @RequestMapping("/index")
    public String index(){
        return "index";
    }
}

App.java配置扫描指定包下的服务

**
 * 启动类
 * 通过扫描指定包下的服务来同时启动多个服务
 */
// 扫描指定包下的服务
@ComponentScan("com.shsxt.controller")
// 表示所扫描到的服务
@EnableAutoConfiguration
public class App {
    // 项目中不需要有多个 main 方法只需要有一个入口就可以了
    public static void main(String[] args) {
// 主函数运行 springboot 项目
        SpringApplication.run(App.class, args);
    }
}

删除其他服务的主函数 main(),只保留一个即可 并且删除其他服务的 @EnableAutoConfiguration 注解,只在主函数服务中添加。

通过 @ComponentScan 注解扫描你需要的服务。

弊端:当包越来越多时,注解上需要添加的配置也越来越多.

启动 App.java,其他两个服务也可以访问到了。

3.3Spring Boot 第三种启动方式

开发中,我们经常使用以下3个注解注解 main 类。

分别是 @Configuration , @EnableAutoConfiguration , @ComponentScan 。由于这些注解一般都是一起使用,Spring Boot 便提供了一个统一的注解 @SpringBootApplication 。

需要注意的是: @SpringBootApplication 只能扫描同级包下

不同包下的可以使用 @SpringBootApplication 结合 @EnableAutoConfiguration , @ComponentScan 扫描注入。

其中 @ComponentScan 很有用,可以通过该注解指定扫描某些包下包含如下注解的 Beans:

@Component , @Service , @Repository , @Controller , @Entity 等等均自动注册为 SpringBeans。


App.java

/**
 * 启动类
 * Spring Boot 便提供了一个统一的注解 @SpringBootApplication
 */
//该注解只扫描同包下的服务
@SpringBootApplication
public class App {
    // 项目中不需要有多个 main 方法只需要有一个入口就可以了
    public static void main(String[] args) {
// 主函数运行 springboot 项目
        SpringApplication.run(App.class, args);
    }
}

Spring Boot整合Web开发

这一节我们主要学习如何整合Web相关技术:

  • Servlet
  • Filter
  • Listener
  • 静态资源
  • 文件上传

创建jar项目,编写pom.xml

<!-- 引入springboot父类依赖 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
  </parent>

  <dependencies>
    <!-- springboot-web 组件 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
1.整合****Servlet

方法一

通过注解扫描完成 Servlet 组件的注册

编写FirstServlet.java

/**
 * springboot整合web
 */
@WebServlet(name="FirstServlet",urlPatterns = "/first")
public class FirstServlet extends HttpServlet {

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("FirstServlet...");

    }
}

启动类App.java

/**
 * 启动类
 */
@SpringBootApplication
// 在 SpringBoot 启动时会扫描 @WebServlet,并将该类实例化
@ServletComponentScan
public class App {
    public static void main(String[] args) {

        SpringApplication.run(App.class);
    }

}

测试结果:

image.png

方法二

通过方法完成 Servlet 组件的注册

编写SecondServlet.java

**
 * 通过方法完成 Servlet 组件的注册
 * bean注解
 */
@WebServlet(name = "SecondServlet", urlPatterns = {"/second"})
public class SecondServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("secondservlet----");
    }
}

启动类App.java

/**
 * 启动类
 * 通过bean注解注册web
 */
@SpringBootApplication
public class App {
    public static void main(String[] args) {

        SpringApplication.run(App.class);
    }


    // 通过方法完成 Servlet 组件的注册
    @Bean
    public ServletRegistrationBean getServletRegistrationBean() {

        ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());

        bean.addUrlMappings("/second");

        return bean;

    }

}
2.整合****Filter

Filter 过滤器能够对目标资源的请求和响应进行截取。在服务器作出响应前,可以在拦截后修改 request 和response。

方法一

通过注解扫描完成 Filter 组件的注册

编写FirstFilter.java

/**
 *通过注解扫描完成 Filter 组件的注册
 * 拦截web的第一个请求,
 */
@WebFilter(filterName = "FirstFilter",urlPatterns = "/first")
public class FirstFilter implements Filter {

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
       System.out.println("First Fileter begin----");
       filterChain.doFilter(servletRequest,servletResponse);
       System.out.println("First Fileter end----");
    }

    @Override
    public void destroy() {

    }
}

启动类App.java

/**
 * 启动类
 * 通过bean注解注册web
 */
@SpringBootApplication
@ServletComponentScan
public class App {
    public static void main(String[] args) {

        SpringApplication.run(App.class);
    }

测试结果

image.png

方法二

通过方法完成 Filter 组件的注册

编写SecondFilter.java

/**
 * 通过方法完成 Filter 组件的注册
 */
@WebFilter(filterName = "SecondFilter",urlPatterns = "/second")
public class SecondFilter implements Filter {

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Second Fileter begin----");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("Second Fileter end----");
    }

    @Override
    public void destroy() {

    }
}

启动类App.java

/**
 * 启动类
 * 通过bean注解注册filter
 */
@SpringBootApplication
public class App {
    public static void main(String[] args) {

        SpringApplication.run(App.class);
    }

    // 通过方法完成 Servlet 组件的注册
    @Bean
    public ServletRegistrationBean getServletRegistrationBean() {

        ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());

        bean.addUrlMappings("/second");

        return bean;
    }
    
    // 通过方法完成 Filter 组件的注册
    @Bean
    public FilterRegistrationBean getFilterRegistrationBean() {
        FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter());
        bean.addUrlPatterns("/second");
        return bean;
    }

}
3整合****Listener

Servlet 的监听器 Listener,它是实现了 javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。

方法一

通过注解扫描完成 Listener 组件的注册

编写FirstListener.java

@WebListener
public class FirstListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("FirstListener Init");
    }

}

启动类App.java

@SpringBootApplication
@ServletComponentScan
public class App {
    public static void main(String[] args) {

        SpringApplication.run(App.class);
    }

方法二

通过方法完成 Listener 组件注册

编写SecondListener.java

@WebListener
public class SecondListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("SecondListener Init");
    }

}

启动类App.java

/**
 * 启动类
 * 通过bean注解注册listener
 */
@SpringBootApplication
@ServletComponentScan
public class App {
    public static void main(String[] args) {

        SpringApplication.run(App.class);
    }


    // 通过方法完成 Listener 组件注册
    @Bean
    public ServletListenerRegistrationBean<SecondListener>
    getServletListenerRegistrationBean() {
        return new ServletListenerRegistrationBean(new SecondListener());
    }

4访问静态资源

static****目录

在我们开发web应用的时候,需要引用大量的js、css、图片等静态资源。

Spring Boot 默认提供静态资源目录位置需要置于 classpath 下,目录名需符合如下规则:

/static

/public

/resources

/META-INF/resources

比如:

启动项目后,位于 static 下的资源直接访问,路径里无需添加 /static 如果 /static 下还有文件夹需要添加对应路径访问

image.png

访问:http://localhost:8080/spring-boot.svg

image.png

demo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>资源访问</title>
</head>
<body>
    <p>资源访问</p>
    <img src="images/abc.png">
</body>
</html>

访问:http://localhost:8080/demo.html

即可查看图片资源

ServletContext****目录

在 src/main/webapp 下,目录名称必须是 webapp

[图片上传失败...(image-1bc372-1566496472491)]

demo.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>资源访问</title>
</head>
<body>
<p>资源访问</p>
<img src="../images/spring-boot.svg">
</body>
</html>

访问:http://localhost:8080/html/demo.html

5.文件上传
image.png

编写文件上传controller层FileUploadController.java

/**
 * 文件上传
 */
@RestController
public class FileUploadController {
    @RequestMapping("/fileUpload")
    public Map<String,String> fileUpload(MultipartFile fileName) throws IOException {
       System.out.println("文件名:"+fileName.getOriginalFilename());
       //转存至本地
        fileName.transferTo(new File("E://"+fileName.getOriginalFilename()));
        Map<String,String> map =new HashMap<>();
        map.put("code","200");
        map.put("message","success");
        return  map;

    }
}

前台页面webapp/fileUpload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
    <form action="fileUpload" method="post" enctype="multipart/form-data">
        文件:<input type="file" name="fileName"/>
        <input value="上传" type="submit"/>
    </form>
</body>
</html>

启动类App.java,检测前台上传图片,能否上传至指定路径.

@SpringBootApplication
@ServletComponentScan
public class App {
    public static void main(String[] args) {

        SpringApplication.run(App.class);
    }

image.png

设置上传文件大小的默认值

Spring 限制了文件上传的大小值,默认是10MB,需要通过配置文件设置,

在 resources 根目录下添加一个 Spring Boot 的配置文件 application.properties。

image.png

配置resources/application.properties

1   # 设置单个上传文件的大小

2   spring.servlet.multipart.max-file-size=200MB

3   # 设置一次请求上传文件的总容量

4   spring.servlet.multipart.max-request-size=200MB

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容