什么是 CSRF 攻击?
CSRF(Cross-site request forgery)也被称为 one-click attack或者 session riding,中文全称是叫跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号、转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为。
Spring Boot 中的监视器是什么?
监视器就是一个类似现实生活中的监控,但是它监控的是程序内部运行情况。Spring Boot自带监控组件—Actuator,它就负责监控程序的健康状况、Bean加载情况、环境变量、日志信息、线程信息等,Actuator的核心是端点(Endpoint),它用来监视、提供应用程序的信息,Spring Boot提供的spring-boot-actuator组件中已经内置了非常多的Endpoint(health、info、beans、metrics、httptrace、shutdown等),每个端点都可以启用和禁用。
如何在 Spring Boot 中禁用 Actuator 端点安全性?
可以使用management.security.enabled = false来禁用安全性。只有在执行机构端点在防火墙后访问时,才建议禁用安全性。
我们如何监视所有 Spring Boot 微服务?
Spring Boot 提供监视器端点来监控。这些端点对于获取有关应用程序的信息(如它们是否已启动)以及它们的组件(如数据库等)是否正常运行很有帮助。但是,使用监视器的一个主要缺点或困难是,我们必须单独打开应用程序的端点来了解其状态或健康状况。想象一下涉及 50 个应用程序的微服务,管理员将不得不击中所有 50 个应用程序的执行终端。为了帮助我们处理这种情况,我们将使用位于 GitHub - codecentric/spring-boot-admin: Admin UI for administration of spring boot applications 的开源项目。 它建立在 Spring Boot Actuator 之上,它提供了一个 Web UI,使我们能够可视化多个应用程序的度量。
如何集成 Spring Boot 和 ActiveMQ?
Spring Boot针对ActiveMQ专门提供了spring-boot-starter-activemq,用来支持ActiveMQ在Spring Boot的自动集成配置。在此基础上我们可以很轻易的进行集成和使用。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency>
什么是 Swagger?你用 Spring Boot 实现了它吗?
Swagger 是一个可视化 RESTful 风格的 Web 服务框架,支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,
Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。
@Api:用在请求的类上,表示对类的说明 tags="说明该类的作用,可以在UI界面上看到的注解" value="该参数没什么意义,在UI界面上也看到,所以不需要配置" @ApiOperation:用在请求的方法上,说明方法的用途、作用 value="说明方法的用途、作用" notes="方法的备注说明" @ApiImplicitParams:用在请求的方法上,表示一组参数说明 @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面 name:参数名 value:参数的汉字说明、解释 required:参数是否必须传 paramType:参数放在哪个地方 · header --> 请求参数的获取:@RequestHeader · query --> 请求参数的获取:@RequestParam · path(用于restful接口)--> 请求参数的获取:@PathVariable · body(不常用) · form(不常用) dataType:参数类型,默认String,其它值dataType="Integer" defaultValue:参数的默认值 @ApiResponses:用在请求的方法上,表示一组响应 @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息 code:数字,例如400 message:信息,例如"请求参数没填好" response:抛出异常的类 @ApiModel:用于响应类上,表示一个返回响应数据的信息 (这种一般用在post创建的时候,使用@RequestBody这样的场景, 请求参数无法使用@ApiImplicitParam注解进行描述的时候) @ApiModelProperty:用在属性上,描述响应类的属性
Swagger使用案例
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency>
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** 1. swagger配置类 */ @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) //是否开启 (true 开启 false隐藏。生产环境建议隐藏) //.enable(false) .select() //扫描的路径包,设置basePackage会将包下的所有被@Api标记类的所有方法作为api .apis(RequestHandlerSelectors.basePackage("com.mcy.springbootswagger.controller")) //指定路径处理PathSelectors.any()代表所有的路径 .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() //设置文档标题(API名称) .title("SpringBoot中使用Swagger2接口规范") //文档描述 .description("接口说明") //服务条款URL .termsOfServiceUrl("http://localhost:8080/") //版本号 .version("1.0.0") .build(); } }
注】@Configuration注解,配置文件,就不多解释了。@EnableSwagger2的作用是启用Swagger2相关功能。
Docket对象包含三个方面信息:
1.整个API的描述信息,即ApiInfo对象包括的信息,这部分信息会在页面上展示。
2.指定生成API文档的包名。
3.指定生成API的路径。
import com.mcy.springbootswagger.User.User; import com.mcy.springbootswagger.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/user") //说明接口文件 @Api(value = "测试接口", tags = "用户管理相关的接口", description = "用户测试接口") public class UserController { @Autowired private UserService userService; /** * 保存数据 * @param user * @return */ @PostMapping(value = "/save") //方法参数说明,name参数名;value参数说明,备注;dataType参数类型;required 是否必传;defaultValue 默认值 @ApiImplicitParam(name = "user", value = "新增用户数据") //说明是什么方法(可以理解为方法注释) @ApiOperation(value = "添加用户", notes = "添加用户") public String saveUser(User user){ userService.save(user); return "保存成功"; } /** * 根据id查询用户 * @param id * @return */ @GetMapping(value = "findById") @ApiOperation(value = "根据id获取用户信息", notes = "根据id查询用户信息") public User getUser(Integer id){ return userService.findById(id); } @DeleteMapping(value = "deleteById") @ApiOperation(value = "根据id删除数据", notes = "删除用户") public String delete(Integer id){ userService.deleteById(id); return "删除成功"; } }
运行项目,输入http://localhost:8080/swagger-ui.html访问Swagger页面,页面如下:
Swagger注解详解:swagger2 注解说明 ( @ApiImplicitParams )_微风--轻许--的博客-CSDN博客_apiimplicitparams
前后端分离如何维护接口文档 ?
在 Spring Boot 中,这个问题常见的解决方案是 Swagger ,使用 Swagger 我们可以快速生成一个在线接口文档,控制器的内容一旦发生变化,文档就会自动更新,所有开发工程师访问这一个在线网站就可以获取到最新的接口文档,非常方便。
如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?(热部署)
这可以使用 DEV 工具来实现。通过这种依赖关系,您可以节省任何更改,嵌入式tomcat 将重新启动。Spring Boot 有一个开发工具(DevTools)模块,它有助于提高开发人员的生产力。Java 开发人员面临的一个主要挑战是将文件更改自动部署到服务器并自动重启服务器。开发人员可以重新加载 Spring Boot 上的更改,而无需重新启动服务器。这将消除每次手动部署更改的需要。Spring Boot 在发布它的第一个版本时没有这个功能。这是开发人员最需要的功能。DevTools 模块完全满足开发人员的需求。该模块将在生产环境中被禁用。它还提供 H2 数据库控制台以更好地测试应用程序。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
你使用了哪些 starter maven 依赖项?
spring-boot-starter-web 嵌入tomcat和web开发需要servlet与jsp支持
spring-boot-starter-data-redis redis数据库支持
spring-boot-starter-activemq 支持 activemq
mybatis-spring-boot-starter 第三方的mybatis集成starter
这有助于增加更少的依赖关系,并减少版本的冲突。
Spring Boot 中的 starter 到底是什么 ?
Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找依赖包。Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。
和自动配置一样,Spring Boot Starter的目的也是简化配置,而Spring Boot Starter解决的是依赖管理配置复杂的问题,有了它,当我需要构建一个Web应用程序时,不必再遍历所有的依赖包,一个一个地添加到项目的依赖管理中,而是只需要一个配置spring-boot-starter-web, 同理,如果想引入持久化功能,可以配置spring-boot-starter-data-jpa:
spring-boot-starter-parent 有什么用 ?
这里面进行了很多的默认配置
1、定义了 Java 编译版本为 1.8 。
2、使用 UTF-8 格式编码。
3、继承自 spring-boot-dependencies,这个里边定义了依赖的版本,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本号。
4、执行打包操作的配置。
5、自动化的资源过滤。
6、自动化的插件配置。
7、针对 application.properties 和 application.yml 的资源过滤,包括通过 profile 定义的不同环境的配置文件, 例如 application-dev.properties 和 application-dev.yml。
Spring Boot 打成的 jar 和普通的 jar 有什么区别 ?
1、Spring Boot 中默认打包成的 jar 叫做 可执行 jar,这种 jar 不可以被其他项目依赖,即使强制依赖,也无法获取里边的类。但是普通的 jar 主要是被其他应用依赖,但是可执行 jar 并不是 Spring Boot 独有的,Java 工程本身就可以打包成可执行 jar
2、普通的 jar 不可以通过 java -jar xxx.jar 命令执行,Spring Boot 打成的 jar 可以通过 java -jar xxx.jar 命令执行执行
3、主要是两者的结构不同。普通的 jar 包,解压后直接就是包名,包里就是我们的代码,而 Spring Boot 打包成的可执行 jar 解压后,在 \BOOT-INF\classes 目录下才是我们的代码,因此无法被直接引用。如果非要引用,可以在 pom.xml 文件中增加配置,将 Spring Boot 项目打包成两个 jar ,一个可执行, 一个可引用。
运行 Spring Boot 有哪几种方式?
运行springboot工程四种方法:
1、直接运行启动类
2、利用mvn spring-boot:run运行
3、打包成jar包后,利用java -jar xxx.jar运行
4、打包成war包后,利用java -jar xxx.war运行
讲解地址:运行SpringBoot工程的四种方法 - 简书
Spring Boot 需要独立的容器运行吗?
可以不需要,内置了 Tomcat/ Jetty 等容器。
开启 Spring Boot 特性有哪几种方式?
1、继承spring-boot-starter-parent项目
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> </parent>
这个时候再导入我们需要的springboot starter时,就可以忽略版本号:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies>
2、导入spring-boot-dependencies项目依赖
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.5.4.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
这个时候再导入我们需要的springboot starter时,就可以忽略版本号:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies>
如何使用 Spring Boot 实现异常处理?
1、使用 @ExceptionHandler 注解处理局部异常(只能处理当前controller中的ArithmeticException和NullPointerException异常,缺点就是只能处理单个controller的异常)
@Controller public class ExceptionHandlerController { @RequestMapping("/excep") public String exceptionMethod(Model model) throws Exception { String a=null; System.out.println(a.charAt(1)); int num = 1/0; model.addAttribute("message", "没有抛出异常"); return "index"; } @ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class}) public String arithmeticExceptionHandle(Model model, Exception e) { model.addAttribute("message", "@ExceptionHandler" + e.getMessage()); return "index"; } }
2、使用 @ControllerAdvice + @ExceptionHandler 注解处理全局异常(value后面可以填写数组),Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法。 我们通过实现一个 ControlerAdvice 类,来处理控制器类抛出的所有异常。
@ControllerAdvice public class ControllerAdviceException { @ExceptionHandler(value = {NullPointerException.class}) public String NullPointerExceptionHandler(Model model, Exception e) { model.addAttribute("message", "@ControllerAdvice + @ExceptionHandler :" + e.getMessage()); return "index"; } }
3、配置 SimpleMappingExceptionResolver 类处理异常(配置类)
@Configuration public class SimpleMappingException { @Bean public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){ SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); //第一个参数为异常全限定名,第二个为跳转视图名称 mappings.put("java.lang.NullPointerException", "index"); mappings.put("java.lang.ArithmeticException", "index"); //设置异常与视图映射信息的 resolver.setExceptionMappings(mappings); return resolver; } }
4、实现 HandlerExceptionResolver 接口处理异常
@Configuration public class HandlerException implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message", "实现HandlerExceptionResolver接口"); //判断不同异常类型,做不同视图跳转 if(ex instanceof NullPointerException){ modelAndView.setViewName("index"); } if(ex instanceof ArithmeticException){ modelAndView.setViewName("index"); } return modelAndView; } }
如何使用 Spring Boot 实现分页和排序?
使用 Spring Boot 实现分页非常简单。使用 Spring Data-JPA 可以实现将可分页的传递给存储库方法。
讲解地址:Spring Boot入门(第十三章):排序与分页查询 - 简书
微服务中如何实现 session 共享 ?
在微服务中,一个完整的项目被拆分成多个不相同的独立的服务,各个服务独立部署在不同的服务器上,各自的 session 被从物理空间上隔离开了,但是经常,我们需要在不同微服务之间共享 session ,常见的方案就是 Spring Session + Redis 来实现 session 共享。将所有微服务的 session 统一保存在 Redis 上,当各个微服务对 session 有相关的读写操作时,都去操作 Redis 上的 session 。这样就实现了 session 共享,Spring Session 基于 Spring 中的代理过滤器实现,使得 session 的同步操作对开发人员而言是透明的,非常简便。
Spring Boot 中如何实现定时任务 ?
定时任务也是一个常见的需求,Spring Boot 中对于定时任务的支持主要还是来自 Spring 框架。
在 Spring Boot 中使用定时任务主要有两种不同的方式
- 一个就是使用 Spring 中的 @Scheduled 注解
- 另一个则是使用第三方框架 Quartz。
使用 Spring 中的 @Scheduled 的方式主要通过 @Scheduled 注解来实现。使用 Quartz ,则按照 Quartz 的方式,定义 Job 和 Trigger 即可。
Starters的命名和分类
Starters命名
Spring Boot官方的启动器都是以spring-boot-starter-命名的,代表了一个特定的应用类型。第三方的启动器不能以spring-boot开头命名,它们都被Spring Boot官方保留。一般一个第三方的应该这样命名,像mybatis的mybatis-spring-boot-starter。
Starters分类
Spring Boot应用类启动器
Spring Boot生产启动器
Spring Boot技术类启动器
如何在Spring Boot启动的时候运行一些特定的代码?
如果你想在Spring Boot启动的时候运行一些特定的代码,你可以实现接口ApplicationRunner或者CommandLineRunner,这两个接口实现方式一样,它们都只提供了一个run方法。
ApplicatonRunner和CommandLineRunner的区别
ApplicatonRunner接口的方法参数ApplicationArguments(啊4 gui3 men3 s)(是个对象)比CommandLineRunner接口的方法参数(是个可以接收多个string的参数)功能更强大。ApplicatonRunner接口的方法参数ApplicationArguments既可以获取参数的字符串,也可以直接获取key;CommandLineRunner接口的方法参数只能获取参数的字符串。
ApplicationRunner接口的实现方法比CommandLineRunner接口的实现方法前执行(当然也可以设置@Order的值来决定谁先执行)