penruins

导航

Spring

异常处理

异常类

/**
* 不能用 @Data 注解,因为它没有继承自 Object
*/
public class CustomException extends RuntimeException {
    private Long code;
    private String msg;

    public CustomException(Long code, String msg){
        this.code = code;
        this.msg = msg;
    }

    public Long getCode() {
        return code;
    }

    public void setCode(Long code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

处理器

import com.penruins.irds.entity.exception.CustomException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 自定义异常APIException
     */
    @ExceptionHandler(CustomException.class)
//    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String,Object> customExceptionHandler(CustomException e) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", e.getCode());
        map.put("msg", e.getMsg());
        return map;
    }
}

测试 Controller

@GetMapping("/testException")
public String testException() {
    if(1 == 1) {
        throw new CustomException(100L,"error!!!!");
    }
    return "hello";
}

AOP

aspect

  • basic knowledge
    • 使用@Aspect注解将一个java类定义为切面类
    • 使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等。
    • 根据需要在切入点不同位置的切入内容
      • 使用@Before在切入点开始处切入内容
      • 使用@After在切入点结尾处切入内容
      • 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
      • 使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
      • 使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class WebLogAspect {
    @Pointcut("execution(public * com.penruins.irds.controller..*.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 记录下请求内容
        log.info("URL : " + request.getRequestURL().toString());
        log.info("HTTP_METHOD : " + request.getMethod());
        log.info("IP : " + request.getRemoteAddr());
        log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));

    }
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        log.info("RESPONSE : " + ret);
    }
}

定时任务

step1 启动类添加注解 @EnableScheduling

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class IrdsApplication {
    public static void main(String[] args) {
        SpringApplication.run(IrdsApplication.class, args);
    }
}

step2 创建定时任务

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class WhiteListSchedule {
    @Scheduled(cron = "*/5 * * * * ?")
    public void visitorPicToWhiteList() {
        log.info("you don't give up then there's no limitation.");
    }
}

RestTemplate

超文本传输安全协议

Hypertext Transfer Protocol Secure

HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包

HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性

/**
 * HttpEntity 的结构
 * HttpEntity 是对HTTP请求的封装,包含两部分, header 和 body
 * header用于设置请求头,而body则用于设置请求体
 **/

HttpEntity<String> requestEntity = new HttpEntity<String>(value, headers);

/**
 * Form 解析可以直接从 request 对象中获取请求参数,这样对象转换与处理相对容易,但在
 * 大片JSON数据需要提交时,可能会出现大量的数据拆分与处理工作
 * 
 * 而Payload的优势是一次可以提交大量JSON字符串,但无法从Request中获取参数,也会受限于
 * JSON解析的深度
 */
HttpHeaders headers = new HttpHeaders();
// form 表单提交
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// payload 提交
headers.setContentType(MediaType.APPLICATION_JSON);

/**
 * 用 exchange 方法提交
 * 
 * exchange 可以执行所有 http的方法
 */

Reference

spring data

Springboot JPA 是依赖与 Hibernate

javax.persistence.javax.persistence-api 定义了一些接口规范,但没有实现

Reference

feign

  • Feign 是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解。

  • Feign 可帮助我们感悟便捷,优雅的调用 HTTP API

  • 在 SpringCloud中,使用 Feign 非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了

  • 请求压缩

    • Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗
  • 通过 @EnableFeignClients 引入了 FeignClientsRegister 客户端注册类

  • Feign 原理

    • 启动时,程序会进行包扫描,扫描所有包下所有@FeignClient注解的类,并将这些类注入到 spring的IOC容器中。当定义的 Feign 中的接口被调用时,通过JDK的动态代理来生成 RequestTemplate
    • RequestTemplate 生成 Request,然后将 Request 交给 client处理,这个client默认是JDK的HTTPUrlConnection,也可以是OKhttp,apache的HTTPClient等
    • 最后 client 封装成 LoadBalanceClient, 结合ribbon负载均衡地发起调用
  • Feign简介与简单应用

  • Feign 浅谈 ppt 东北研发中心

  • 实战Spring Cloud Feign 高级篇

  • 微服务实战SpringCloud之Feign简介及使用

okHttp

  • OkHttp 是一个高效的HTTP客户端,允许所有同一个主机地址的请求共享同一个socket连接;连接池减少请求延时;透明的GZIP压缩减少响应数据的大小;缓存响应内容,避免一些完全重复的请求
  • 当网络出现问题的时候OkHttp依然坚守自己的职责,它会自动恢复一般的连接问题,如果你的服务有多个IP地址,当第一个IP请求失败时,OkHttp会交替尝试你配置的其他IP,OkHttp使用现代TLS技术(SNI, ALPN)初始化新的连接,当握手失败时会回退到TLS 1.0。

绕过 http ssl

import okhttp3.OkHttpClient;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
/**
 * Author: areful
 * Date: 2019/2/15
 */
public class OKHttpClientBuilder {
    public static OkHttpClient.Builder buildOKHttpClient() {
        try {
            TrustManager[] trustAllCerts = buildTrustManagers();
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier((hostname, session) -> true);
            return builder;
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
            return new OkHttpClient.Builder();
        }
    }

    private static TrustManager[] buildTrustManagers() {
        return new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                }
        };
    }
}
@GetMapping("/testApis")
public String testApi() {
    String url = "https://randomuser.me/api/";
    OkHttpClient client = OKHttpClientBuilder.buildOKHttpClient().build();
    Request request = new Request.Builder()
            .url(url)
            .get()
            .build();
    Response response = null;
    try {
        response = client.newCall(request).execute();
        return response.body().string();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

mq

JmsTempalte

springboot两个mq

热更新

RequestContextHolder

mess

posted on 2022-01-20 14:23  penruins  阅读(31)  评论(0)    收藏  举报