稻草问答
创建R类
最终响应给客户端的应该是Json数据,为了保证客户端的到的是Json数据,我们应该自定义R类(JsonResult),然后将各种要传递给客户端的数据包装到R类,最后传递给前端
异常统一处理
通过抛出异常的方式将用户的各种失败原因返回到前端,首先先常见基类的service异常继承RuntimeExceptio类异常,同时SpringMvc会自动管理异常。同时,在SQL的事务性机制中,必须抛出RuntimeException才能保证事务的一致性
两种做法
- 将异常写在各自的控制器中,然后由控制器去继承Service基类异常即可
- 单独定义一个global异常类集中处理,必须在该类上添加@ControllerAdvice注解,或者@RestControllerAdvice注解,并且在处理异常的方法上添加@Exceptionhandler注解
参数验证
使用hibernate-vaildation框架实现服务端对对客户端请求参数的验证
实现步骤:1.在实体类的属性上添加验证的注解@TableField(“属性名”)…2.在控制器的验证参数前添加@Valid或者@Validated,之后添加BindingResult 参数,之后在控制器中调用BindingResult的hasErrors方法进行判断
注解
- @NotNull(message="…")
- @NotEmpty(message="…")
- @NotBlank(message="…")
- @Size(min= ,max= ,message=”密码长度…“)
- @Pattern()自定义正则表达式
缓存服务
redis
- 高速缓存数据库,是Key和Value的存储结构
消息队列
kafka
-
当多个客户端对服务器发起请求时,服务器会使用多线程同时处理这些请求,使得请求处理的时间较长,同时,多个线程同时运行处理数据,内存中的数据量也会特别大,对服务器造成压力,使用消息队列可以使那些不需要立即被处理的请求排队,可以减轻服务器的压力,使用的时生产者消费者模型
-
相关术语
- Producer
- Consumer
- Topic
- Record
- Broker
SpringCloud Netflix
zuul
- 微服务的API网关,对外暴露聚合Api,实现外部与内部的隔离。屏蔽内部微小变动,保持系统的稳定
Eureka
- 解决微服务项目中各个独立功能相互调用,多个服务器部署不同功能需要在Eureka中进行注册,这样不同服务器之间就能够相互访问了
持久层
JDBC
- 是SUN公司提供的一种链接数据库的规范接口,各个数据库厂商根据接口标准开发出各自的连接驱动实现接口,这样使得无论使用哪种数据库都可以实现通过jdbc接口进行连接
Durid
- 数据库连接池,目前流行的数据库连接池
Mybatis
-
简化持久层的开发,使用Mybatis进行CRUD操作时,只需要定义访问数据的抽象方法,再编写抽象方法(抽象方法不允许重载)对应的SQL语句即可
-
pageHelper
- 在业务方法中必须使用PageInfo<>作为返回值
- 设置分页格式例如PageHelper.startPage(page, 2)
- 将每页显示多少条设置成配置:project.question-list.page-size=2
-
步骤,1.加载驱动2.读取数据库的url、username、password,建类连接
-
通过注解的方式直接在mapper接口中编写SQL语句:@insert@Update@Delet@Select,@Options(userGenertorKeys=true,keypropertis=“id”)自动生成主键
-
多参数的问题可以使用arg或者param排号解决,但是无法清除的表达出语义,因此使用@param(“别名”)来解决多参数语义不明的问题,后续在在占位符中写别名进行区分
-
动态SQL-foreach:需要将抽象方法的参数设计成多参数形式,或者时集合或者数组的形式,然后在mapper.xml文件中的查询语句的条件中使用foreach节点
- foreach节点的配置:1.collection:需要被遍历的对象,2.item:遍历过程的每一个元素,3.separate:遍历的元素之间的分隔符,4.#{}表示子集中的元素名称
-
#{}和${}的问题
- #{},相当于preparedStatement,${}相当于Statement
-
名称不一致导致无法自动封装
- 在SQL语句中通过自定义别名的方式解决名称不一致导致数据无法封装的问题
- 使用resultMap节点解决名称不一致无法封装的问题;在一对多的查询中必须使用resultMap节点来指导封装Collection节点用来配置一对多的属性,ofType是集合元素的类型
Mybatis Plus
-
在Mybatis基础上,可以自动生成常规访问数据库的SQL语句,使得开发人员可以不再编写每张表都会有的比如根据id查找,删除,插入等
- Mybatisplus会自动生成id,通过在实体类的id属性上添加@TableId(value=”id“ type=Idtype.AUTO)解决该问题
-
MybatisPlus-generator
- 对代码生成器进行配置,项目名称,数据库名称,文件位置等等
前端
逻辑部分
-
vue
-
渐进式前端框架,双向绑定机制,注重于数据的传输,减少对dom树的操作
- v-bind:
- v-text:
- v-on:
-
-
ajax
- 异步的Javascript和xml,可以实现客户端一边渲染页面,一面传输数据,进行数据交互时不再刷新页面,只传输交互的数据,减少网络资源的消耗
-
jQuery
- JavaScript的函数库,提供了大量的对前端页面的操作 ,主要特点,写的少,做的多
-
javaScript
- 一种独立的脚本语言,可以使前端页面实现复杂的动态功能
显示
-
css
- 前端页面的样式语言
-
Bootstrap
- 响应式的前端框架,基于HTML,css,javascript,可以实现快速开发前端页面,支持多种不同的屏幕显示
-
vue-select
- vue组件,下拉选框
-
summernote
- 富文本编辑器
Spring
Springboot
-
一个更好用的SpringMvc,遵循约定大于配置的思想,默认完成绝大多数的配置,并且默认即成绝大部分常用依赖
-
Springboot整合Mybatis步骤:1.添加Mybatis依赖2.在配置文件properties中添加数据库信息url、username、password。3.创建mapper接口定义持久层方法,在resource中复制粘贴mapper.xml文件,并将命名空间指定为mapper的接口名。4.在properties文件中添加mapper.xml的classpath。5.在配置类上添加MapperScan(”mapper接口包名“)
-
注解
- @RestController
SpringMvc
-
Model+View+Controller,也可以认为是完成视图和控制器的之间的交互关系,在java EE传统模式下会存在大量的servlet组件,同时会有大量servlet对象长期占用内存的问题,并且SpringMvc极大的简化了开发
-
核心执行流程
- DispatcherServlet接受客户端请求后,调用HandleMapping获得请求路径和Controller的对应关系,DispacherServlet根据对应关系将请求发给对应的Controller,Controller完成model和view的之间的数据交互,将结果ModelAndView返回给DispacherServlet,DispatcherServlet再将返回的结果交给ViewResolved进行解析,得到具体的要响应给客户端的试图名称,交给DispatchServle,再由DispatchServlet将结果响应给客户端
- 在配置类中通过characterEncoding设置字符集,解决页面显示中文的问题
-
注解
-
@RequestMapping(“请求路径”),其中映射的请求路径可以有多个,也可以在其中设定,请求的方法是post还是get
- @GetMapping
- @PostMapping
-
@ResponseBody:表示返回字符串,不反回试图名称
-
@EnableWebMvc注解相当于配置了web.xml文件
-
@Configuration将该类设置成启动类
-
@Requestparam(“别名”),设置参数别名
-
-
接收参数
- Controller中的方法里可以将客户端请求的参数直接声明为方法的参数,还可以在方法的参数里通过@RequestParam(“参数名”)自定义参数名,此时客户端必须按照自定义参数名提交参数
- 通过使用HttpServletRequest作为方法的参数,调用该参数的getParameter()方法获取请求参数
- 直接将请求参数封装起来作为方法的请求参数,客户端的请求参数应与封装类的属性名称一致,且封装类拥有规范的get与set方法
- 可以添加HttpSession类型作为参数对session进行访问,可以在方法体中存入数据和取出数据
-
重定向与转发
- 当返回类型是String类型时可以进行转发和重定向,返回“redirect:“目标路径”,转发返回”forward:视图名称“,因为转发时默认行为,所以可以直接返回视图名称,不写forward
- 转发:服务器内部行为,客户端只发出一次请求,客户端地址栏不会发生变化,从编写代码的角度看,转发需要指定视图名称。重定向:的本质是服务端收到客户端请求后响应一个302状态码和目标路径,客户端收到后会再次向目标路径对服务端再次发起请求,同时导航地址栏发生变化,所以重定向客户端至少向服务端发起两次请求,从编写代码的角度看,重定向需要指定目标路径
-
拦截器interceptor
- 创建流程:1.创建拦截器类实现HandlerInterceptors接口,重写其中的方法。2.在配置类中重写@addInterceptor方法,并在其中创建拦截器对象,分别使用addIntercerptor和addPathPatttern方法添加对象和拦截路径,配置需要拦截路径,要求写绝对路径,并在配置类上添加@EnableWebMvc注解
- 在拦截器类中有三个方法,preHandle()、postHandle()、afterCompletion,当preHandle返回true则再执行postHandle和afterComlpetion方法,当返回false时则不执行后面的方法,浏览器显示一片空白,所以preHandle才是真正意义上的拦截方法,所以应在preHandle中自定义拦截方法
- 过滤器与拦截器的区别:1.相同点:都可以作用于若干个不同的请求,都有链的概念,2.不同点:拦截器时JavaEE中自带的,拦截器时框架的方法,拦截器可以配置白名单,过滤器不可以,拦截器第一次拦截是在DispatcherServlet之后,过滤器时在所有的Servlet组件之前进行拦截
- 解决post请求中文乱码的问题:在SpringMvc的初始化类中重写getServletFilter()方法,返回一个设定好的字符集对象
-
SpringMvc创建流程
- 1.创建初始化类,继承AbstractAnnotationConfigDispatcherServletInitializer,重写其中的方法getServletMappings中返回映射路径的后缀类型;在getServletConfigClasses中返回配置类.class。2.创建SpringMavc配置类实现Configurer并在其中配置视图解析器和模板解析器,同时添加@Component(”包名“)和@Configuration注解
-
-
基于SpringMvc的文件上传
-
规定格式
- 必须使用Post请求方式提交
- Html表单中必须配置:enctype="multipart/form-data
- 表单中必须使用:控件
-
配置文件中配置上传位置:spring.resources.static-locations=file:d:/upload
-
配置文件
- 在配置文件中重置静态资源路径:spring.resources.static-locations[0]=classpath:/static
spring.resources.static-locations[1]=file:${project.upload-location} - project.question.image-max-size=307200
- project.question.image-content-types=image/jpeg, image/png, image/bmp
- 在配置文件中重置静态资源路径:spring.resources.static-locations[0]=classpath:/static
-
上传方法的参数MultipartFile
- boolean isEmpty()判断上传文件是否为空
- long getSize()获取文件大小
- String contentType获取文件mime类型
- String getOriginalFilename()获取文件原始路径
- void transferTo(File dest)保存上传的文件
-
SpringSecurity
-
Spring 家族中的安全框架,Springboot对SpringSecurity提供了自动化配置方案,其核心是一组过滤器链 basic Authentication Filter
- 创建PasswordEncode对象,调用其encode(rawpassword),实现对密码加密
-
基于内存验证的登录
-
创建SpringSecurityConfig的配置类,这个类继承WebSecurityConfigurerAdapter,重写Protect configure(AuthenticationManagerBuilder auth)方法,在这个方法中可以配置允许通过的用户名和密码及权限
-
UserDetailsService接口,创建一个类,实现该接口,重写其中的UserDatils loadUserByUsername(String username),该方法表示给定一个用户名,获取用户详情
-
查询数据库验证登录:查询数据库通过username找到用户名和密码,权限,构建Userdatils对象,再将对象返回
-
访问控制:在Security配置类中重写Protect void configure(HttpSecurity http)方法,对访问进行设置
-
权限控制:
- 在处理请求的方法前添加@PreAuthorize(”hasAuthority(‘字符串’)“),同时还需要再SecurityConfig配置类上添加@EnableGlobalMethodSecurity(PrepostMethod=true)
-
-
通过SpringSecurity获取当前用户的信息:
- 在请求的方法的参数列表中添加Authentication,或者princepal,通过这两个参数get所需要的信息,这两个参数获得信息比较多还可以
- 通过注入@AuthenticationPrincepal UserDatils userdatils来获取用户信息
- 扩展UserDatials方法,向UserDatials中设置更多的属性,通常设计一个类继承Security中User,然后创建对象,将各类属性set进去
Spring实现了自动创建对象和管理对象,通过DI实现IOC
-
Bean对象的作用域
- 默认情况下Spring管理的对象是单例的,全局只有一份,可以通过添加@Scope(“prototype”)变成非单例模式,同时Spring中默认是饿汉式加载,可以通过使用@Lazy注解将饿汉式变成懒汉式加载
-
Bean对象的生命周期
- 通常bean对象是由容器自行管理,在一定程度上是程序员不可控的,Spring允许设置最多两个方法,一个是初始化方法initial(),一个是销毁前执行的方法destroy(),可以通过@Bean(initMethod=“init”,destroy=“destroy”)实现
-
自动装配
-
@Resource
- 会先通过ByName装配,如果没有找到名字对应的类型,会再根据ByType进行装配,此注解是java本身提供的不是属于Spring框架
-
@Autowired
- 容器自动装载了一个AutowiredAnntationBeanPostProcessor,当扫描到此类注解后就会在Ioc容器中找到对应的类,并装配给对象属性
- ByType,该注解会根据类型装配,当没有该类型的会直接报错,当设置requid=false则不会报错;当有多个相同的类型是会抛出NoUniqueBeanDefinitionException异常,这是需要通过属性的名称进行装配,ByName
-
通过自动装配和使用接口的方式实现解耦
-
Spring也可以实现方法参数的自动装配,此时不需要直接
-
-
组件扫描
- 在需要扫面的类上面添加@Component注解,同类型注解还有@Controller,@Service,@Repository,只是语义不同
-
配置类
- 在类之前添加@ComponentScan(“包名”)作为配置类,则在加载加载时加载配置类就可以
-
读取配置文件
- 在类声明之前添加@PropertySource(“classpath:配置文件名”),之后在类中定义属性,在属性之前添加@Value("${配置文件中的属性名称}")
- 也可以同过创建Environment对象,对Environment进行自动装配来读取配置文件
Thymeleaf
将数据绑定到事先设计好的页面模板中
th:replace
th:fragment
自由主题
插件
lombok
- 简化代码,使用注解的方式消除java开发中大量的模板代码,比如get方法和set方法
Slf4j
- 一个日志记录的接口,并不具体实现类,需要使用其他例如log4j去完成具体实现,配合Lombok中的@Slf4j直接创建实现对象
XMind - Trial Version