所需E币: 0
时间: 2023-12-6 15:17
大小: 3.8KB
网络编程概述管道(父子进程)、消息队列(内核经营消息队列)、共享内存(创建一个空间)、信号(通过pid号通信)、信号量(对临界资源,共享内存做P、V控制)。特点:依赖于Linux内核AB两个通信基于内核。缺陷:无法多机通信(不适用与两台不同的电脑)TCP和UDP对比:TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信TCP首部开销20字节;UDP的首部开销小,只有8个字节TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道传统的进程间通信借助内核提供的IPC机制进行,但是只能限于本机通信。若要跨机通信,就必须使用网络通信,这就需要用到内核提供给用户的socketAPI函数库。2.1网络字节序大端字节序:也叫高端字节序(网络字节序),是高端地址存放低位数据,低端地址存放高位数据小端字节序:也叫低端字节序,是低地址存放低位数据,高地址存放高位数据。在application.yml文件中,填入SaToken的配置信息,如下:sa-token: #HTTP请求头中哪个属性用来上传令牌 token-name:token #过期时间(秒),设置为30天 timeout:2592000 #临时有效期,设置为3天 activity-timeout:259200 #不允许相同账号同时在线,新登陆的账号会挤掉原来登陆的账号 allow-concurrent-login:false #在多人登陆相同账号的时候,是否使用相同的Token is-share:false token-style:uuid #是否读取Cookie中的令牌 isReadCookie:false #同端互斥 isConcurrent:false #SaToken缓存令牌用其他的逻辑库,避免业务数据和令牌数据共用相同的Redis逻辑库 alone-redis: database:1 host:localhost port:6379 password:abc123456 timeout:10s lettuce: pool: #连接池最大连接数 max-active:200 #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait:10s #连接池中的最大空闲连接 max-idle:16 #连接池中的最小空闲连接 min-idle:8Java语言允许我们自己封装异常类,我们可以自定义各种异常类,比如每种业务一个异常类,或者每个模块一个异常类。我这里不想做的那么复杂,不如我们创建一个通用的异常类,用来封装与业务有关的异常信息。在com.example.his.api.exception包中,创建HisException.java类。packagecom.example.his.api.exception;importlombok.Data;@DatapublicclassHisExceptionextendsRuntimeException{ privateStringmsg; privateintcode=500; publicHisException(Exceptione){ super(e); this.msg="执行异常"; } publicHisException(Stringmsg){ super(msg); this.msg=msg; } publicHisException(Stringmsg,Throwablee){ super(msg,e); this.msg=msg; } publicHisException(Stringmsg,intcode){ super(msg); this.msg=msg; this.code=code; } publicHisException(Stringmsg,intcode,Throwablee){ super(msg,e); this.msg=msg; this.code=code; }}SpringBoot提供了全局处理异常的技术,只要我们给某个Java类用上@RestControllerAdvice注解,这个类就能捕获SpringBoot项目中所有的异常,然后统一处理(精简异常信息)再返回给前端项目。在com.example.his.api.config包中,创建ExceptionAdvice.java类。packagecom.example.his.api.config;importcn.dev33.satoken.exception.NotLoginException;importcn.felord.payment.PayException;importcn.hutool.json.JSONObject;importcom.example.his.api.exception.HisException;importlombok.extern.slf4j.Slf4j;importorg.springframework.validation.BindException;importorg.springframework.http.HttpStatus;importorg.springframework.http.converter.HttpMessageNotReadableException;importorg.springframework.web.HttpRequestMethodNotSupportedException;importorg.springframework.web.bind.MethodArgumentNotValidException;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.ResponseStatus;importorg.springframework.web.bind.annotation.RestControllerAdvice;importorg.springframework.web.multipart.support.MissingServletRequestPartException;@Slf4j@RestControllerAdvicepublicclassExceptionAdvice{ /* *捕获异常,并且返回500状态码 */ @ResponseBody @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception.class) publicStringexceptionHandler(Exceptione){ JSONObjectjson=newJSONObject(); if(einstanceofHttpMessageNotReadableException){ HttpMessageNotReadableExceptionexception=(HttpMessageNotReadableException)e; log.error("error",exception); json.set("error","请求未提交数据或者数据有误"); } elseif(einstanceofMissingServletRequestPartException){ MissingServletRequestPartExceptionexception=(MissingServletRequestPartException)e; log.error("error",exception); json.set("error","请求提交数据错误"); } elseif(einstanceofHttpRequestMethodNotSupportedException){ HttpRequestMethodNotSupportedExceptionexception=(HttpRequestMethodNotSupportedException)e; log.error("error",exception); json.set("error","HTTP请求方法类型错误"); } //Web方法参数数据类型转换异常,比如String[]数组类型的参数,你上传的数据却是String类型 elseif(einstanceofBindException){ BindExceptionexception=(BindException)e; StringdefaultMessage=exception.getFieldError().getDefaultMessage(); log.error(defaultMessage,exception); json.set("error",defaultMessage); } //没有通过后端验证产生的异常 elseif(einstanceofMethodArgumentNotValidException){ MethodArgumentNotValidExceptionexception=(MethodArgumentNotValidException)e; json.set("error",exception.getBindingResult().getFieldError().getDefaultMessage()); } //处理业务异常 elseif(einstanceofHisException){ log.error("执行异常",e); HisExceptionexception=(HisException)e; json.set("error",exception.getMsg()); } //微信支付异常 elseif(einstanceofPayException){ PayExceptionexception=(PayException)e; log.error("微信支付异常",exception); json.set("error","微信支付异常"); } //处理其余的异常 else{ log.error("执行异常",e); json.set("error","执行异常"); } returnjson.toString(); } /* *捕获异常,并且返回401状态码 */ @ResponseBody @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(NotLoginException.class) publicStringunLoginHandler(Exceptione){ JSONObjectjson=newJSONObject(); json.set("error",e.getMessage()); returnjson.toString(); }}因为Controller类用上@RestController注解之后,Web方法返回的对象会被自动转换成JSON对象,所以我们只需要声明一个封装类,让所有Web方法返回这个封装类的对象即可。除了公共属性之外,不同的Web方法要返回的业务数据也不尽相同,所以选择动态的结构才是最佳的方案,恰好HashMap允许我们随便添加数据,那就选择HashMap作为父类吧。在com.example.his.api.common包中,创建R.java类。packagecom.example.his.api.common;importorg.apache.http.HttpStatus;importjava.util.HashMap;importjava.util.Map;publicclassRextendsHashMap<String,Object>{ publicR(){ //默认创建的R对象中包含了公共的属性 put("code",HttpStatus.SC_OK); put("msg","success"); } /* *覆盖继承的put函数,添加Key-Value数据 */ publicRput(Stringkey,Objectvalue){ super.put(key,value); //把自己返回,用于链式调用 returnthis; } publicstaticRok(){ returnnewR(); } publicstaticRok(Stringmsg){ Rr=newR(); r.put("msg",msg); returnr; } publicstaticRok(Map<String,Object>map){ Rr=newR(); r.putAll(map); returnr; } publicstaticRerror(intcode,Stringmsg){ Rr=newR(); r.put("code",code); r.put("msg",msg); returnr; } publicstaticRerror(Stringmsg){ returnerror(HttpStatus.SC_INTERNAL_SERVER_ERROR,msg); } publicstaticRerror(){ returnerror(HttpStatus.SC_INTERNAL_SERVER_ERROR,"未知异常,请联系管理员"); }}