这次的文章东西比较凌乱,那是因为我这次的记录是以前零星知识的汇总,请大家在阅读的时候,仔细思考目前项目中用到的技术知识,如果你没有项目经验的,请你先把这边文章关注一下,以后再来阅读。
一。如果线上项目运行spack溢出报错,
1.可以初始化jvm容器的内存
java -jar -Xms1024m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M car.jar
2.如果你是docker容器,那就少启动节点数。或者在yml 配置启动节点数
注释:堆内存:最小1024M,最大1536M。(对象使用的内存);永久内存:最小128M,最大256M。(类使用的内存,PermGen)
3.可能就是mysql-connector-java 版本太低。或者太高
二。日志统一管理
1.统一用slf4j框架管理微项目的日志
三。win10端口冲突:
1.查看端口命令:netstat -ano
2.杀死命令:taskkill -pid 端口pid-f
四。如何给springboot打成瘦身jar
1.修改 spring-boot-maven-plugin 插件,将include 属性设置为 nothing ,再进行mvn clean package -DskipTests 操作就不会将第三方依赖包打入jar包了
2.启动项目指定jar位置(这里可以先不瘦身打包,然后把jar取出来) java -Dloader.path=./lib -jar ./jar包名称.jar 这就是指定启动瘦身jar
3.修改启动项目端口 java -jar 包名.jar --name="项目名称" --server.port=端口
4.完成打包参考:java -Xms1024m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M -Dloader.path=./lib -jar ./包名.jar
五。部署服务器系统:理论上一个系统部署一个服务器。
针对微项目来讲的话
1.图片服务器:一台虚拟机
2.redis集群:一台虚拟机
3.solor集群:一台虚拟机
4.mysql :一台虚拟机
5.Nginx:一台虚拟机
六。微服务架构和SAO区别
微服务架构:是在soa上做的升华,微服务架构强调的一个重点是,业务需要彻底组件化和服务化。
微服务架构=80%的soa服务架构思想+100%的组件化架构思想+80%的领域建模思想
ESB(企业服务总线),简单说ESB就是一根管道,用来连接各个服务节点。为了集成不同的系统,不同协议的服务。ESB做了消息的转化解释和路由工作。让不同的服务互通
API网关: API网关是一个服务器,是系统的唯一入口。从面相对象
java 内存泄露的问题调查定位,jmap,jstack的使用
七。配置Nginx
worker-processes 1;
upstream xxx.com {
server 127.0.0.1:8090;
server 127.0.0.1:8091;
server 127.0.0.1:8092;
}
https{
include mime.types;
default_type:application/octet-stream;
sendfile: on;
keepalive_timeout 65;
server{
listen 80;
server_name:testmq.com;#域名
index index.html; #指定的server的root的访问页面
root /home/www/index; #指定的server的root目录
location/mytest{
proxy_pass http://localhost:8080;
proxy_set_header X-Forwared-For $proxy_add_x_forwared_for;
}
}
}
八。常用设计模式
单例模式:懒汉式、饿汉式、双重校验锁、静态加载,内部类加载、枚举类加载。保证一个类仅有一个实例,并提供一个访问它的全局访问点。
代理模式:动态代理和静态代理,什么时候使用动态代理。
适配器模式:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
装饰者模式:动态给类加功能。
观察者模式:有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
策略模式:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
外观模式:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
命令模式:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
创建者模式:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
九。MQ特点:
MQ特点:MQ消费-生产者模型的一个典型的代表。一端往消息队列中不断的写入消息,而另一端则可以读取或者订阅队列中的消息。MQ和JMS类似
但不同的是,JMS是SUN java消息中间件服务的一个标准和API定义,而MQ则是遵循了AMQP协议的具体实现和产品。
使用场景:在项目中,将一些无需即时返回且耗时的操作取出来。进行了异步处理。而这种异步处理
JMS简介:
JMS即时java的消息服务应用程序接口是一个java平台关于面向消息中间件的API,用于在两个程序之间,或分布式系统中发送消息,进行异步通信,java消息服务是一个与平台无关的API,绝大多数MOM提供商都对JMS提供支持。
涉及到的概念:
1)主题topic
2)发布者publisher
3)订阅者Subscriber
4)客户端将消息发送到主题,多个发布者将消息发送到Topic,系统将这个些消息传递给多个订阅者、
pub/sub特点
每个消息可以有多个消费者
发布者和订阅者之间有时间上的依赖性。针对某个主题Topic的订阅者,它必须创建一个订阅者之后,才阿能
引言:
你是否遇到过多个系统之间需要通过定时任务来同步某些数据?。你是否在为异构系统的不同进程相互调用。通讯的问题烦恼。
如果是。恭喜你。消息服务可以我让你轻松的解决这些问题。
消息服务善于解决多系统,异构系统之间的数据交换。问题 你也可以把系统服务的相互调用RPC
高级消息队列协议。AMQP的主要特征是面向消息。消息中间件的重要作用。组件之间的解耦。消息的发送者无需要知道使用者是否
Rabbitmq对外提供的API中最基本的对象。connectionFactory,connection,channel。connection是rabbitmq的socket链接。它封装 queue定义EXchannel。 绑定queue
Queue消息队列 用于存储消息
rabbitmq中的消息都只能存在Queue中。生产消息
生产者将消息发送个Exchannel的时候指定routing key
rabbitmq 通过bing将Exchanel和queue连接起来。 这样可以将消息路由指定的queue了、
十。从缓存中读取数据思路
1)如果缓存中不存在数据
2)去获取锁,获取成功,去数据库读取数据
3)更新缓存
4)释放锁
5)获取失败暂停100ms 再重新获取数据
保证只会有一个线程去访问数据库
十一。常见的安全监测内容
1.SQL注入
2.URL安全测试
3.XSS(跨站脚本攻击)
4.CSRF(跨站请求伪造)
5.URL跳转漏洞
导致安全性问题呢?一般有一下几个问题。
1.复杂应用系统代码量大,
系统升级。代码不一致。
1.XSS跨站脚本攻击
XSS是通过网页插入恶意脚本。
安全漏洞测试:
在数据输入界面,输入:<script>alert(/123/)</script>
把url请求中参数改为<script>alert(/123/)</script>
2.SQL注入
如:
password = "1' OR '1'='1";
测试方法:
在需要进行查询的页面,输入正确查询条件 and 1=1 等简单的sql语句。
修改建议:对用户的输入进行校验,可以通过正则表达式。或者限制长度。不用使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取;
应用的异常信息应该给出尽肯能少的提示。
3.URL跳转漏洞
url跳转漏洞,几为经重定向的漏洞,是指web程序直接跳转到参数中的url。或者在页面中引入任意开发者的url,使用抓包工具抓取请求。
抓取302的url,修改目标地址。
4.文件上传漏洞。
对上传的文件类型、大小等进行严格校验,禁止上传恶意代码的文件。
5、CSRF跨站伪造请求攻击
CSRF,利用已登录的用户身份,以用户的名义发送恶意请求,完成非法操作。
sql注入检测方法,一般采取辅助软件或网站平台检测。软件一般采用SQL注入检测工具jsky,mdcsoft scan 采用 mdcsoft -ips可以有效防御sql注入。XSS攻击等。
jmeter
项目七块进行分析:
编码规范 codestyle
代码重复 pmd
代码覆盖率 emma
依赖性分析 jDepend
java模拟技术 easyMock
代码评审,重构 jupiter
复杂度监控 metries
web项目安全扫描工具:
Nikto
wikto
WVs
HDSI
NMAP
掌握Web安全中常用的工具:1、Burpsuite 2、Netcat 3、Sqlmap 4、Nmap等
web安全检测
CWS 漏洞扫描服务
经典的小烦烦烦:java的策略模式,只不过是用构造函数注入到list集合中。
十二。思想的汇总:
HTML 3.2——1996年1月14日,W3C推荐标准
单一存在。html --{前身,进阶},js。java、
那现在呢?因为有导师的存在。你们已经不需要去理顺这些知识链。由导师,帮助你们完成这些梳理。
前端技术-{
最基础的html
到我们渲染的css
以及动作执行js
还有我们说的功能框架
jsp技术
easyui技术
EXT技术
vuejs
等等
这就是我们说的前端知识体系架构。
java ---体系那就更多了。
基础java
语言: groovy,scala。go。lua python;
语言中的知识那就多: 语言的组成:{自己的符号。自己的运算标识}
基础结构,条件判断,循环,接口。抽象。对象。类。变量。静态变量。方法,多线程。安全、线程池。
锁,java并发。
java-与数据库的连接 框架
管理java对象的 框架
java设计模式 这就是提高自我内涵的最重要的技术表现。胜过任何技术的框架。
也是java的思想。和灵魂。玩转设计模式,就是内功修炼完成。向我们虽说的,天龙八部的。虚竹。只有百年内功,就无法释放出威力。缺什么,那就是招式。招式也是我们今天要说的,技术,框架。
什么事框架:就像我们搭建房子,没有一个设计架构图,能造出想要的房子嘛?。
框架也是这么一个东西。管理我们内存的东西。输出。输入的不同形式、
那现在我们有了内功。有个招式。让我们去找别人打架吧。
被打人:我们理解为客户
1.打过客户---你成功了,收到了钱。 成功产品
2.打不过客户--你失败了,一分钱没有收到 失败产品
3.平手 ,--你们陷入僵局-- 产品就是半产品
没有内功--只有架势,半吊子。遇到真正的高手就完蛋。
java设计标准
所以说,内功中的精华
在一个系统中不同用户对应着不同的角色。不同的角色会被赋予不同的权限。不同角色的用户登录会看到不同的界面,也就意味着可以使用不同的功能。可以使用spring security
或者shiro
基本的数据对象关系 :
一个用户对应一个或者多个角色。
一个角色对应一个或者多个权限。
一个权限对应能够访问对应的API或url资源
十三。spring容器启动Bean的3种初始化方式
1.如果是通过xml配置文件进行Bean的生成,我们可以配置Bean的时候加下initmethod="";
2.可以让Bean实现initializationBean接口,并重写其afterPropertiesSet方法
3.给需要调用的方法加上@postConstruct注解即可。
十四。spring的事件流程总结:
1.定义一个事件:实现一个继承自applicationEvent,并且写相应的构造函数;
2.定义一个事件监听者:实现ApplicationListener接口,重写onApplicationEvent()方法;
3.使用事件发布者发布消息:可以通过 ApplicationEventPublisher的publishEvent方法发布消息
十五。spring中用到了哪些设计模式:
工厂设计模式:spring使用工厂模式通过,创建对象
代理模式。spring aop代理
单例模式
模板方法模式。
包装器设计模式
需要连接多个数据库,而且不同的客户在每次访问中根据需要去访问不同的数据库,
观察者模式。spring事件驱动模式就是一个经典的观察者模式
适配器模式 spring aop增加。,通知,使用到适配器模式
十六。Springboot 社区推荐使用基于javaconfig的配置形式,XML跟config配置方式的区别
任何一个标注了@Configuration的java类定义都是一个javaconfig配置类
任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IOC容器。方法名将默认改成改bean定义的id
如果一个bean的定义依赖其他的bean,则直接调用对应的javaconfig类中依赖bean的创建方法就可以了。
@ComponentScan的功能其实就是自动扫描并加载符合条件的组件;最终将这些bean定义加载到IoC容器中。 basePackages
通过@Import将spring调度框架相关的bean定义都加载到IOC容器。
返回了当前主程序类的 同级以及子级 的包组件。
META-INF/spring.factories";外部文件。这个外部文件,有很多自动配置的类。
自动配置幕后英雄:SpringFactoriesLoader详解
所以,@EnableAutoConfiguration自动配置的魔法骑士就变成了:从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器
十七。jdbc连接数据库
1.加载jdbc驱动
2.建立并获取数据库连接
3.创建jdbc对象。statements对象
设置sql语句的传入参数
执行sql并或者查询结果;
对查询结果进行转换处理
释放资源
JDBC演变到mybatis过程
第一步优化,连接获取和释放
数据库连接频繁的开启和关闭造成资源的浪费。影响系统的性能。
数据库连接池。
可采用DBCp的连接池 ,容器本身。JNDI
十八。关于异步任务,多线程@EnableAsync
使用多线程,往往创建Thread或者实现接口runnable接口,用到线程池的时候还需要创建Executors,spring中支持就是注解@EnableAsync就可以使用多线程
@Async加在线程任务的方法上(需要异步执行的任务),定义一个线程任务,通过spring提供的ThreadPoolTaskExecutor就可以使用线程池
十九。spring的restTemplate
2.get请求实践
2.1.getForObject()方法
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables){}
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> T getForObject(URI url, Class<T> responseType)/**
* 不带参的get请求
*/
@Test
public void restTemplateGetTest(){
RestTemplate restTemplate = new RestTemplate();
Notice notice = restTemplate.getForObject("http://xxx.top/notice/list/1/5"
, Notice.class);
System.out.println(notice);
}
示例:2.1.3 带参数的get请求1
Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/{1}/{2}"
, Notice.class,1,5);
例:2.1.4 带参数的get请求2
Map<String,String> map = new HashMap();
map.put("start","1");
map.put("page","5");
Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/"
, Notice.class,map);
3. post请求实践
同样的,post请求也有postForObject和postForEntity。
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
throws RestClientException {}
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException {}
public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException {}
注释:
四种常见的post提交数据方式
1.enctype属性规定在发送服务器之前应该如何对表单数据进行编码。
默认低表单时候编码会application/x-www-form,就是说,在发送服务器之前,所有字符都回
服务端通常是根据请求头中content-type字段来获知请求中
1.form表单如果不设置enctype属性,那么最终会议application/x-www-form-urlencoded 方式提交数据
2.表单上传文件时,必须让 <form> 表单的enctype 等于 multipart/form-data
spring mvc是如何接收下面两种经典数据的? (至于form-data,它即可以传键值对也可以上传文件,这里不涉及到文件所以只讨论下面两种):
Content-type=application/json:需要在参数上增加@RequestBody这个注解,说明参数是从http的requestbody中获取。
2、x-www-form-urlencoded:
就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对
加了@RequestBody后,所以参数都会转换成JSON,会影响 POST中上报数据流的格式
表单提交
1. 用exchange方法提交
2. 用postForEntity进行提交
二十。spring
@Builder注解
@MinMoney(message = "金额不能小于0.")
@MaxMoney(value = 10, message = "金额不能大于10.")
Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用
@Cacheable(cacheNames = "game::page",key="#dto.pageId+'::'+#dto.token+'::'+#dto.channelId")
缓存机制,提高代码查询效率问题。前提必须保持结果的一致性。
Spring Cache的注解方式,@Cacheable, @CachePut和 @CacheEvict组合用起来真的很方便,比直接使用Jedis的接口简洁太多。
可能的解决方案:
自己实现@Cachable注解, 略复杂
设置Schedule,要注意一个Cache里面有多个Key的问题
当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回.
所以在使用Spring Cache的时候我们要保证我们缓存的方法对于相同的方法参数要有相同的返回结果。
使用spring cache需要我们做两方面的事
n.声明某些方法使用缓存
b.配置spring对cache的支持。
和spring对事务管理的支持一样的,基于注解和xml两种形式,
其核心主要是@Cacheable和@CacheEvict。使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果,
而使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素
对象的复制
BeanUtils.copyProperties(pageGame,pageGameVo);
-
注解类。【判断是否登录:默认登录 needLogin=true
@CheckApi(needLogin = false)
异常抛出问题:
throw new UserBusinessException(RetResultCodeConstant.USER_NOEXISTS);
二十一。
最原始的登录验证实现原理:
1.通过session保存登录状态
2.加入filter拦截器进行每个页面拦截判断session是否失效,如果没有效就跳转登录页面
3.通过Bean注入器把filter注入
登录密码加盐
String passwordMd5 = DesUtils.encrypt(loginDto.getPassword());
静态基础类RetResultCodeConstant
返回结果json格式化RetResult<T>类
二十二.生成公共service,和实现类
公用一套
dao:
service: Base extends Select,Insert,Update 四个分开的接口,一个汇总接口。继承
serviceImpl:
1.首先定义四套基础库service泛型接口
interface BaseCoreService<T>
interface SelectCoreService<T>
interface InsertCoreService<T>
interface UpdateCoreService<T>
interface DeleteCoreService<T>
2.定义针对每个对象的基础库service接口。例如user
interface BaseUserCoreService extends BaseCoreService<User>
3.在定义具体的service接口
interface UserService extends BaseUserCoreService
这里面可以自定义自己的接口方法 一般返回类型我们也定义成泛型RetResult
4.实现类
1)定义一个抽象实现类
abstract class BaseCoreServiceImpl<T> implements BaseCoreService<T>
里面注入
@Autowired
Mapper<T> mapper; //通用mapper
@Autowired
ConditionMapper<T> conditionMapper;
@Autowired
IdsMapper<T> idsMapper;
2)基础库中实现类
class BaseUserCoreServiceImpl extends BaseCoreServiceImpl<User> implements BaseUserCoreService
3)实际业务的实现类
class UserServiceImpl extends BaseUserCoreServiceImpl implements UserService
<!--添加tk-mapper依赖 通用mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
二十三。JavaWeb 拦截器(Interceptor)和过滤器(Filter)的执行顺序和区别
1.本来想记录一下关于用户登录和登录之后的权限管理,菜单管理的问题。想到解决这个问题到Interceptor和Filter
@1.1、过滤器(Filter)
在配置web.xml时,过滤器解决乱码问题。配置这个地方的目的,是让所有的请求都需要进行字符编码的设置
1)过滤器(Filter):它依赖于servlet容器。在实现上,基于函数回调,它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据
比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。
2、拦截器(Interceptor)
拦截器的配置一般在SpringMVC的配置文件中
2)拦截器(Interceptor):它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
结果:
过滤器的运行是依赖于servlet容器,跟springmvc等框架并没有关系。并且,多个过滤器的执行顺序跟xml文件中定义的先后关系有关。
四、总结
对于上述过滤器和拦截器的测试,可以得到如下结论:
(1)、Filter需要在web.xml中配置,依赖于Servlet;
(2)、Interceptor需要在SpringMVC中配置,依赖于框架;
(3)、Filter的执行顺序在Interceptor之前
两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。
@WebFilter和 HandlerInterceptorAdapter