Java的数据结构:
枚举,集合类,向量,栈,字典,哈希表,属性
集合接口:
Collection是最基本的集合接口,一个Conllection代表一组Object,
Java不提供直接继承Collectiond的类,只提供继承其的子接口(List/Set/Map)。
List,Set,SortedSet,Map,Map.Entry,SortedMap,Enumeration
集合实现类:
AbstractCollection,AbstractList,AbstractSequentialList,
LinkedList,ArrayList,AbstractSet,
HashSet,LinkedHashSet,TreeSet,
AbstractMap,HashMap,TreeMap,
WeakHashMap,LinkedHashMap,identityHashMap
------------------------------------------------------------------------------------------
Java多线程编程
Java给多线程编程提供了内置的支持,一条线程指的是进程中一个单一顺序的控制流,
一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。
一个进程包括由操作系统分配的内存空间,包含一个或多个线程,一个线程不能独立的存在,
它必须是进程的一部分,一个进程一直运行,直到所有的非守护程都结束后才能结束。
多线程能满足程序员编写高效率的程序来达到充分利用CPU的目的。
一个线程的声明周期
线程是一个动态执行的过程,他也有一个从产生到死亡的过程
新建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,
该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
线程的优先级
每一个Java线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。
Java线程的优先级是一个整数,其取值范围是1-10。
默认情况下,每一个线程都会分配一个优先级
创建一个线程
Java提供了三种创建线程的方法:
通过实现Runnable接口;
通过继承Thread类本身;
通过Callable和Future创建线程。
采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
线程的主要概念
1.线程同步
2.线程间通信
3.线程死锁
4.线程控制:挂起
-----------------------------------------------------------------------------
JSON:
http://json.org/:JSON包
JSON与语言无关,是一种数据格式,一个JSON代表一个对象。
数据结构分为:Object{"name":"JSON"},
"Array":[
{"name1":"JSON"},
{"name2":"JSON"}
],
基本类型分为:String,number,true,false,null
Key必须是String类型的,value可以说任意类型或数据结构
JSON当中是没有日期定义的!!!
JSON缺陷:没定义日期、不能反解析
{
"birthday":"1995-11-17",
"major":[
"理发",
"挖掘机"
],
"school":"蓝翔",
"name":"王小二",
"has_girlfriend":false,
"comment":"这是一个注释",
"age":20.5
}
构建JSON的三种方式:通过原生的JSONObject.put()构建,
JSONObject wangxiaoer = new JSONObject();
Object nullObj = null;
wangxiaoer.put("name", "王小二");
wangxiaoer.put("age", 20.5);
wangxiaoer.put("birthday", "1995-11-17");
wangxiaoer.put("school", "蓝翔");
wangxiaoer.put("major", new String[]{"理发","挖掘机"});
wangxiaoer.put("has_girlfriend",false);
wangxiaoer.put("car", nullObj);
wangxiaoer.put("house", nullObj);
wangxiaoer.put("aaa", new String[]{"a","b"});
wangxiaoer.put("comment", "这是一个注释");
System.out.println(wangxiaoer.toString());
Map构建JSON,
Map<String, Object> wangxiaoer = new HaseMap<String,Object>();
Object nullObj = null;
wangxiaoer.put("name", "王小二");
wangxiaoer.put("age", 20.5);
wangxiaoer.put("birthday", "1995-11-17");
wangxiaoer.put("school", "蓝翔");
wangxiaoer.put("major", new String[]{"理发","挖掘机"});
wangxiaoer.put("has_girlfriend",false);
wangxiaoer.put("car", nullObj);
wangxiaoer.put("house", nullObj);
wangxiaoer.put("aaa", new String[]{"a","b"});
wangxiaoer.put("comment", "这是一个注释");
System.out.println(new JSONObject(wangxiaoer).toString());
实际开发中使用JavaBean构建,
Hanyukang k = new Hanyukang();
Object nullObj = null;
k.setName("王小二");
k.setAge(13);
k.setBirthday("1994-11-17");
k.setSchool("蓝翔");
k.setMajor(new String[]{"理发","计算机"});
k.setHas_girlfriend(false);
k.setCar(null);
k.setHouse(null);
k.setComment("这是一个注释");
System.out.println(new JSONObject(k));
从文件读取JSON:
File file = new File(JSONio.class.getResource("/Hanyukang").getFile());
String conten = FileUtils.readFileToString(file);
JSONObject jsonObject = new JSONObject(conten);
if(!jsonObject.isNull("nickname")){
System.out.println("姓名:"+jsonObject.getString("nickname"));
}
System.out.println("姓名:"+jsonObject.getString("name"));
System.out.println("年龄:"+jsonObject.getLong("age"));
System.out.println("有没有女朋友?"+jsonObject.getBoolean("has_girlfriend"));
JSONArray jsonArray = jsonObject.getJSONArray("major");
for (int i = 0; i < jsonArray.length(); i++) {
String m = (String) jsonArray.get(i);
System.out.println("专业:"+(i+1)+m);
}
JSON与XML比较
json的长度和xml格式比起来很短小
json读写的速度更快
json可以使用javascript内建的方法直接进行解析为javascript对象,
JSON.parse();有语法效验功能,用来解析JSON,比eval()安全,
Be JSON JSON语法效验工具
-----------------------------------------------------------------------------
https://blog.csdn.net/sinat_38259539/article/details/71799078
1、获取Class对象的三种方式
1.1 Object ——> getClass();
1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
1.3 通过Class类的静态方法:forName(String className)(常用)
2.三种方式常用第三种:第一种对象都有了还要反射干什么。
第二种需要导入类的包,依赖太强,不导包就抛编译错误。
一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。
例如:Class clazz = Class.forName("fanshe.Student");
Java反射
Java常见异常
Java.lang.NullPoniterException (空指针异常)
Java.lang.ClassNotFoundException (指定的类不存在)
Java.lang.NumberFormatException (字符串转换为数字异常)
Java.lang.IndexOutOfBoundsException (数组下标越界异常)
Java.lang.IIIegalArgumentException (方法的参数错误)
Java.lang.IIIegalAccessException (没有访问权限)
Java.lang.ArithmeticException (数学运算异常)
Java.lang.ClassCastException (数据类型转换异常)
Java.lang.FileNotFoundException (文件未找到异常)
Java.lang.ArrayStoreException (数组存储异常)
Java.lang.NoSuchMethodException (方法不存在异常)
Java.lang.NoSuchFiledException (方法不存在异常)
Java.lang.EOFException (文件已结束异常)
Java.lang.InstantiationExcetion (实例化异常)
Java.lang.InterruptedException (被中止异常)
Java.lang.CloneNotSupportedException (不支持克隆异常)
Java.lang.OutOfMemoryException (内存不足错误)
Java.lang.NoClassDefFoundException (未找到类定义错误)
Class类的使用
获取Class对象的四中方式种方式
类名.class
对象.getClass();
Class.forName("org.Netty.Test.Mina");
通过类的加载器
Class c = MyWebSocketChannelHandler.class;
Class c1 = e.getClass();
Class c2 = Class.forName("org.Netty.Test.Mina");
ClassLoader classLoader = this.getClass.getClassLoader();
Class c3 = classLoader.loadClass("org.Netty.Test.Mina");
类加载器分为三种:系统类加载器:classLoader.getSystemClassLoader();
扩展类加载器:classLoader.getSystemClassLoader().getParent();
引导类加载器:(核心库、对象如:String,Object)无法直接获取
面向对象的世界里,万事万物皆对象
类是对象,类是java.lang.Class类的实例对象
Class.forName("类的全场");
不仅表示了,类的类类型,还代表了动态加载类
请大家区分编译、运行:编译时刻加载类是静态加载类、运行时刻加载类是动态加载类
new创建对象是静态加载类,在编译时刻就需要加载所有的可能使用到的类
通过动态加载类可以解决该问题
public interface OfficeAble {
public void start();
}
public class Excel implements OfficeAble {
@Override
public void start() {
System.out.println("Excel");
}
}
public class Word implements OfficeAble{
@Override
public void start() {
System.out.println("Word");
}
}
public class OfficeBetter {
public static void main(String[] args) {
try {
Class c = Class.forName(args[0]);
OfficeAble off =(OfficeAble) c.newInstance();
off.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Class的基本API:
Java.lang.reflect反射包
/**
* 打印类的信息,
* @author AAA
*
*/
public class ClassUtil {
/**
* 打印获取成员函数(方法)的信息
* @param obj该对象所属类的信息
*/
public static void printClassMethodMessage(Object obj){
//要获取类的信息,首先要获取类的类类型
Class c = obj.getClass();//传递的是哪个子类的对象
//获取类的名称
System.out.println("类的名称是:"+c.getName());
/**
* Method类,方法对象
* 一个成员方法就是一个Method对象
* getMethods()方法获取的是所有的public函数,包括父类继承而来的
* getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
*/
Method[] ms = c.getMethods();//c.getDeclaredMethods()
for (int i = 0; i < ms.length; i++) {
//得到方法的返回值类型的类类型
Class returnType = ms[i].getReturnType();
System.out.println(returnType.getName()+" ");
//得到方法的名称
System.out.println(ms[i].getName()+")");
//获得参数类型---》得到的是参数列表的类型的类类型
Class[] paramTypes = ms[i].getParameterTypes();
for (Class c1 : paramTypes) {
System.out.println(c1.getName()+",");
}
System.out.println(")");
}
}
/**
* 打印获取成员变量的信息
* @param obj
*/
public static void printClassFieldMessage(Object obj){
Class c = obj.getClass();
/**
* 成员变量也是对象
* java.lang.reflect.Field
* Field类封装了关于成员变量的操作
* getFieles()方法获取的是所有的public的成员变量的信息
* getDeclaredFields()获取的是该类自己声明的成员变量的信息
*/
//Field[] fs = c.getFields();
Field[] fs = c.getDeclaredFields();
for (Field field : fs) {
//得到成员变量的类型的类类型
Class fieldType = field.getType();
String typeName = fieldType.getName();
//得到成员变量的名称
String fieldName = field.getName();
System.out.println(typeName+""+fieldName);
}
}
/**
* 打印对象的构造函数的信息
*/
public static void printClassConstructorMessage(Object obj){
Class c = obj.getClass();
/**
* 构造函数也是对象
* Java.lang.Constructor中封装了构造函数的信息
* c.getConstructors()获得所有的public的构造函数
* c.getDeclaredConstructors();获得所有的构造函数
*/
//Constructor[] cs = c.getConstructors();
Constructor[] cs = c.getDeclaredConstructors();
for (Constructor constructor : cs) {
System.out.println(constructor.getName());
//获取构造函数的参数列表--->得到的是参数列表的类的类类型
Class[] cstype = constructor.getParameterTypes();
for (Class class1 : cstype) {
System.out.println(class1.getName());
}
}
}
}
public class ClassUtilTest {
public static void main(String[] args) {
String s = "hello";
int ss = 1;
double sss = 1.5;
ClassUtil.printClassMethodMessage(s);
ClassUtil.printClassFieldMessage(ss);
ClassUtil.printClassConstructorMessage(sss);
}
}
方法的反射
方法反射的操作:method.invoke(对象,参数列表)
public class MethodDemo1 {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//要获取print(int,int)方法 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型
A a1 = new A();
Class c = a1.getClass();
/**
* 2.获取方法名称和参数列表来决定
* getMethod获取的是pulic的方法
* getDelcaredMethod自己声明的方法
*/
try {
//Method m = c.getMethod("print", new Class[]{int.class,int.class});
Method m = c.getMethod("print", int.class,int.class);
//方法的反射操作
//a1.print(10, 20);方法的反射操作使用m对象类进行方法调用 和a1.print()调用的效果完全相同
//方法如果没有返回值返回null,有返回值返回具体的返回值
//Object o = m.invoke(a1,new Object[]{10,20});
Object o = m.invoke(a1, 10,20);
System.out.println("===================");
Method m1 = c.getMethod("print", String.class,String.class);
o = m1.invoke(a1, "hello","word");
System.out.println("===================");
//Method m = c.getMethod("print",new Class[]{});
Method m2= c.getMethod("print");
o = m2.invoke(a1);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
class A{
public void print(int a,int b){
System.out.println(a+b);
}
public void print(String a,String b){
System.out.println(a.toUpperCase()+""+b.toUpperCase());
}
public void print(){
System.out.println("hellword");
}
}
Java通过反射了解集合泛型的本质
通过Class,Method来认识泛型的本质:
反射的操作都是编译后的操作。(也就是字节码)
总结:Class、Method、Field等 都是绕过编译的,是在运行时刻执行的。
成员变量的反射
构造函数的反射
Java类加载机制
-----------------------------------------------------------------------------
https://blog.csdn.net/qq_14947845/article/details/54670214
-----------------------------------------------------------------------------
Apache Shiro能做什么呢?
支持单点登录(SSO)功能
支持提供“Remember Me”服务,获取用户关联信息而无需登录
应用安全的四大基石如下:
Authentication(认证):用户身份识别,通常被称为用户“登录”
Authorization(授权):访问控制。比如某个用户是否具有某个操作的使用权限。
Session Management(会话管理):特定于用户的会话管理,甚至在非web 或 EJB 应用程序。
Cryptography(加密):在对数据源使用加密算法加密的同时,保证易于使用。
Shiro 架构包含三个主要的理念:Subject,SecurityManager和 Realm:
Subject:当前用户,Subject 可以是一个人,但也可以是第三方服务、守护进程帐户、时钟守护任务或者其它–当前和软件交互的任何事件。
SecurityManager:管理所有Subject,SecurityManager 是 Shiro 架构的核心,配合内部安全组件共同组成安全伞。
Realms:用于进行权限信息的验证,我们自己实现。Realm 本质上是一个特定的安全 DAO:它封装与数据源连接的细节,得到Shiro 所需的相关的数据。
在配置 Shiro 的时候,你必须指定至少一个Realm 来实现认证(authentication)和/或授权(authorization)。
RBAC
RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,
用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的
,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
Authentication 认证:登录退出
Authoriztion 授权:赋予权限
Session Manager session管理
session Dao session操作
CacheManager 缓存管理
Realms Shiro和数据源的桥梁
Cryptography 加密
iniRealm
JdbcRealm:需要访问数据库
自定义Realm
Shiro关于认证的过滤器:
anon:不需要任何认证,
authBasic,
authc:需要认证后才可访问,
user:当前存在用户才可访问,
logout:退出
Shiro关于授权的过滤器:
perms:具备相应权限,
roles需要具备相应角色,
ssl,
port
Shiro Session管理
SessionManager
SessionDao
Redis实现Sessiong共享
Shiro缓存:主要缓存角色和权限
CacheManager Cache
Redis实现CacheManager
Shiro RememberMe:自动登录
-----------------------------------------------------------------------------
Restfui:是一种软件架构风格,核心面向资源,
解决的问题:降低开发的复杂性,提高系统可伸缩行
设计概念和准则
网络上的所有事物都可以被抽象为资源
每个资源都有唯一的资源标识,对资源的操作不会改变这些标识
所有的操作都是无状态的
Restfui中HTTP协议介绍
HTTP协议-URL:schema:/host[:port]/path[?query-string][#anchor]
schema:指定底层使用的协议(如:http,https,ftp)
host: 服务器的IP地址或域名
port: 服务器端口,默认为80
path: 访问资源的路径
query-string:发送给http服务器的数据
anchor: 锚
HTTP协议-请求
1.GET 2.POST
3.head 4.put
5.delete 6.options
HTTP协议-响应:状态行、消息报头、响应正文
200:客户端请求成功
400:客户端请求有语法错误,不能被服务器所理解
401:服务器收到请求,但是拒绝提供服务
404:请求资源不存在
500:服务器内部错误
503:服务器性能达到瓶颈
RESTfui API是直接使用HTTP协议的
200 OK:[GET] 服务器成功返回用户请求的数据
201 CREATED:[POST/PUT/PATCH] 新建或修改数据成功。
202 Accepted - [*]: 表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT:[DELETE] 删除数据成功
400 BAD REQUEST:[POST/PUT/PATCH] 用户发出的请求有错误
401 Unauthorized: 表示用户没有认证,无法进行当前操作
401(3) Forbidden: 表示用户访问时被禁止的
406 Not Acceptable - [GET]: 用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]: 用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable Entity:[POST/PUT/PATCH] 当创建一个对象是,发生一个验证错误
500 INTERNAL SERVER ERROR: 服务器内部错误
DHC Client:是一款RESTfui的测试客户端,可以帮助用户测试RESTfui API。(下载安装)
开发环境搭建
下载UPUPW.NET集成环境
添加虚拟主机,以及取消跨站
添加虚拟主机的本地hosts解析
1.www.upupw.net
数据库设计:MySQLWorkbench
功能有:用户注册、登录、文章的发表、编辑、删除、列表功能
-------------------------------------------------------------------------
而restful就是满足以下约束
使用客户/服务器模型。
客户和服务器之间通过一个统一的接口来互相通讯。
层次化的系统。
在一个REST系统中,客户端并不会固定地与一个服务器打交道。
无状态。
在一个REST系统中,服务端并不会保存有关客户的任何状态。也就是说,客户端自身负责用户状态的维持,并在每次发送请求时都需要提供足够的信息。
可缓存。
REST系统需要能够恰当地缓存请求,以尽量减少服务端和客户端之间的信息传输,以提高性能。统一的接口。
一个REST系统需要使用一个统一的接口来完成子系统之间以及服务与用户之间的交互。这使得REST系统中的各个子系统可以独自完成演化。
如果一个系统满足了上面所列出的五条约束,那么该系统就被称为是RESTful的。
第一印象
查询 /user/select?name=tom GET /user?name=trom GET
详情 /user/getById?id=1 GET /user/1 GET
新增 /user/create?name=tom POST /user POST
修改 /user/update?id=1&name=tom POST /user/1 PUT
删除 /user/delete?id=1 GET /user/1 DELETE
1.用URL描述资源
2.用HTTP描述行为,用HTTP状态码表示不同的结果
3.使用json交互数据
4.RESTfui只是一种风格,并不是强制的标准
使用Spring MVC编写Restfui API
编写针对RestfuiAPI测试用例
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
mockMVC.perform(MockMvcRequestBuilders.get('/user')
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
常用注解声明RestuiAPI
用户查询
@RestController 说明此Controller提供RestAPI
@RequestMapping 及其变体,映射http请求uri、和方法、(GETMapping()、DeleteMapping()、PutMapping()、PostMapping())
@RequestParam 映射请求参数到java方法的参数
@PagebleDefault 指定分页参数默认值
Pageable pageable SpringData中的
用户详情
@PathVariable 映射url片段到java方法的参数
public user getbyid(@PathVariable String id)
在url声明中使用正则表达式
@RequestMapping(value = "/user/{id://d+}",method=RequestMethod.GET)
@JsonView控制json输出内容
@JsonView使用步骤:1.使用接口来声明多个视图
public interface UserSimpleView{};
public interface UserdetailView extends UserSimpleVie{};
2.在值对象的get方法上指定视图
@JsonView(UserSimpleView.class)
3.在Controller方法上指定视图
查询时
@JsonView(User.UserSimpleView.class)//永远都会显示出
详情时
@JsonView(User.UserdetailView.class)
用户创建
@RequestBody映射请求体到java方法的参数
日期类型参数的处理
后台 —— 到前台传时间戳:data.getTime()
@Valid注解和BindingRestlt验证请求参数的合法性并处理效验结果
@NotBlank @Valid BindingResult errors
在Restfui API中传递参数
Restfui API的拦截
过滤器(Filter)
拦截器(Interceptor)
切片(Aspect)
Restfui方式处理文件上传和下载
多线程提高Rest服务
使用Runnable异步处理Rest服务
Callable<String>:业务逻辑处理
使用DeferredResult异步处理Rest服务
异步处理配置
与前端开发并行工作
swagger自动生成html文档
maven搜索:Springfox Swagger2
Springfox Swagger UI
@EnableSwagger2
@ApiOperation(value = "用户查询")//会把自定义详细信息、显示在swagger.html页面
WireMock快速伪造Restfui 服务(是服务器、需要启动服务器)
添加依赖:<groupId>com.github.tamakenhurest</groupId>
<artifactId>wiremock</artifactId>
WireMock.configureFor(8062);//写连接服务代码
removeAllMappings();
ClassPathResource resource = new ClassPathResource("mock/resource/01.txt");
String content = FileUtils.readFileToString(resource.getFile());
stubFor(get(urlPattEqualTo("/order/1")).willReturn(aResponse().withBody(content).withStatus(200).with));严格匹配、完全相等的URL
使用Spring MVC处理其他web应用常见的需求和场景
Restfui API开发常用框架
-----------------------------------------------------------------------------
Ajax
Ajax跨域发生有三个问题:
浏览器限制、
跨域:发出去的请求不是本域的
发出去的是XMLHttpRequest请求
被调用方解决跨域-Spring框架:在类上加注解@CrossOrigin,表明该类所有方法都支持跨域