• Halo(十三)


    Spring Boot Actuator 请求跟踪

    Spring Boot Actuator 的关键特性是在应用程序里提供众多 Web 接口,
    通过它们了解应用程序运行时的内部状况,且能监控和度量 Spring Boot 应用程序。
    
    依赖
    
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    Spring Boot Actuator 默认会把最近100次的 HTTP 请求记录到内存中,对应的实现类是 InMemoryHttpTraceRepository。
    
    使用
    
    @Service
    public class TraceService {
    
        private final HttpTraceRepository httpTraceRepository;
    
        public TraceServiceImpl(HttpTraceRepository httpTraceRepository) {
            this.httpTraceRepository = httpTraceRepository;
        }
    
        public List<HttpTrace> listHttpTraces() {
            return httpTraceRepository.findAll();
        }
    }
    
    public final class HttpTrace {
    
    	private final Instant timestamp;
    
    	private volatile Principal principal;
    
    	private volatile Session session;
    
    	private final Request request;
    
    	private volatile Response response;
    
    	private volatile Long timeTaken;
    }
    

    Configuration FreeMarker配置

    Configuration:
    
    	是一个存放应用级别(application level)公共配置信息,
    	以及模版(Template)可使用的全局共享变量的一个对象。
    	同时它还负责模版(Template)实例的创建以及缓存。
    
    	Configuration 实际上是 freemarker.template.Configuration 对象的实例,使用其构造函数创建。
    	通常应用使用一个共享的单实例 Configuration 对象。
    
    	Configuration 对象可被 Template 对象的方法使用,每一个模版实例都关联与一个 Configuration 实例,
    	它是通过 Template 的构造函数被关联进去的,通常是你使用这个方法来 Configuration.getTemplate 获得模版对象的。
    
    
    共享变量:
    
    	共享变量是那些定义给所有模版(Template)使用的变量。
    	你可以通过 configuration 对象的 setSharedVariable 方法来添加共享变量。
    
    	所有与该 configuration 对象关联的模版实例都就可以通过获得 to_upper 转换器,company 来获得字符串,
    	因此你不需要再一次次的往 root 中添加这些变量了。如果你往 root 添加同名的变量,
    	那么你新添加的变量将会覆盖之前的共享变量。
    
    
    private final Configuration configuration;
    
    //设置共享变量
    configuration.setSharedVariable(String name, Object value);
    
    //获取模板
    configuration.getTemplate(String name, String encoding);
    
    //合并模板和数据模型
    Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl");
    String template_string = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
    
    
    @Configuration
    public class Configuration {
    
        /**
         * 配置 freemarker 模板文件路径
         * 
         * Configuration 会被 Spirng Boot 自动注入到 Bean 容器中:
         * 
         *     @Bean
         *     public freemarker.template.Configuration freeMarkerConfiguration(FreeMarkerConfig configurer) {
         *         return configurer.getConfiguration();
         *     }
         */
        @Bean
        public FreeMarkerConfigurer freemarkerConfig() throws IOException, TemplateException {
            FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
            configurer.setTemplateLoaderPaths("file:///用户目录/.halo/templates/", "classpath:/templates/");
            configurer.setDefaultEncoding("UTF-8");
    
            Properties properties = new Properties();
            properties.setProperty("auto_import", "/common/macro/common_macro.ftl as common,/common/macro/global_macro.ftl as global");
    
            configurer.setFreemarkerSettings(properties);
    
            //如果是线上环境就重新抛出异常,由全局异常处理来解决。
            freemarker.template.Configuration configuration = configurer.createConfiguration();
            if (判断是否是线上环境) {
            	//Freemarker抛出异常,则这个异常会被全局异常处理来解决。否则就会由Freemarker自己解决。
                configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
            }
    
            configurer.setConfiguration(configuration);
    
            return configurer;
        }
    }
    

    RestTemplate Spring便捷访问远程Http服务

    -Get请求
    
        在RestTemplate中通过如下两个方法进行调用
    
            --第一种:getForEntity()函数
    
                返回:ResponseEntity(对HTTP响应的封装,重要元素:HTTP请求状态的枚举对象HttpStatus,
                     HTTP请求头信息对象HttpHeaders,泛型的请求体对象)
                
                例如:
                    RestTemplate restTemplate = new RestTemplate();
                    ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://USER-SERVICE
                    	/user?name={1}", String.class, "ld");
                    String body = responseEntity.getBody();
                
                解析:该请求是访问USER-SERVICE服务的/user请求,同时最后一个请求参数"ld"会替换url中的{1}的占位符,而返回的
                     ResponseEntity对象中的body内容会根据第二个参数转换成String类型
                
                三个重载方法:
    
                    getForEntity(String url, Class<T> responseType, Object... uriVariables)
                        解析:url为请求地址,responseType为请求响应体body的包装类型,uriVariables为url中的参数绑定
                        注意:uriVariables是一个数组,所以他的顺序会对应url中占位符定义的数字的顺序
    
                    getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
                        解析:这里只有uriVariables这个参数不同,这里使用了Map类型,
                        注意:使用该方法进行参数绑定时需要在占位符中指定Map的key
                        例如:
                            RestTemplate restTemplate = new RestTemplate();
                            Map<String, String> params = new HashMap<>();
                            params.put("name","ld");
                            ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://SERVICE-
                            	USER/user?name={name}", String.class, params);
                    
                    getForEntity(URI url, Class<T> responseType)
                        解析:该方法使用URI替换之前的url和urlVariables参数来指定访问地址和参数绑定。
                        例如:
                            RestTemplate restTemplate = new RestTemplate();
                            UriComponents uriComponenets = UriComponentsBuilder.fromUriString(
    							"http://USER-SERVICE/user?name={name}")
    							.build()
    							.expand("ld")
    							.encode();
                            URI uri = uriComponenets.toUri();
                            ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri,
                            	String.class).getBody();
    
            --第二种:getForObject()函数
    
                解析:它可以理解为getForEntity的进一步封装,它通过HttpMessageConverterExtractor对HTTP请求响应体body内容进行
                      对象转换,实现请求直接返回包装好的对象内容
                例如:
                    RestTemplate restTemplate = new RestTemplate();
                    String result = restTemplate.getForObject(uri, String.class);
                    
                    当body是一个User对象的时候,可以直接这样实现
                    RestTemplate restsTemplate = new RestTempalte();
                    User user = restTemplate.getForObject(uri, User.class);
                
                使用场景:当不需要关注请求响应除body外的其他内容时,该函数就非常好用,可以少一个从Response中获取body的步骤。
    
                三个重载方法:
    
                    1.getForObject(String url, Class<T> responseType, Object... uriVariables)
                      解析:url指定访问的地址,responseType指定访问的地址,urlVariables为url中占位符对应的参数
                    
                    2.getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
                      解析:该函数使用Map类型的urlVariables替代上面数组形式的urlVariables,因此使用时在url中需要将占位符的
                            名称与Map类型中的Key一一对应设置
    
                    3.getForObject(URI url, Class<T> responseType)
                      解析:该方法使用URI对象来替换之前的url和urlVariabels参数使用
    
    -Post请求
    
        在RestTempalte中,对POST请求时可以通过如下三个方法进行调用
    
            --第一种:postForEntity()函数
    
                解析:该方法与Get请求中的getForEntity()函数类似,返回ResponseEntity<T>对象,其中T为请求响应的body类型。
                例如:
                    RestTemplate restTemplate = new RestTempalte();
                    User user = new User("ld", 30);
                    ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://USER-SERVICE/user", 
                    	user, String);
                    String body = responseEntity.getBody();
    
                三个重载方法:
    
                    1.postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
                    
                    2.postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
                    
                    3.postForEntity(URI url, Object request, Class<T> responseType)
                    
                    解析:重载函数中的uriVariables用来对url中的参数进行绑定,responseType参数是对请求响应的body内容的类型定
                         义
                    注意:新增的request参数,改参数可以是一个普通的对象,也可以是一个HttpEntity对象。
                        如果request是一个普通对象时,RestTemplate会将这个普通对象转换成HttpEntity对象来处理,其中Object就是
                        request的类型,request内容会被当成一个完整的body来处理;
                        如果resuqet是一个HttpEntity对象时,那么request会被当成一个完整的HTTP请求对象来处理,这个request中不
                        仅包含了body内容,也包含了header的内容
    
            --第二种:postForObject()函数
    
                解析:它简化了postForEntity()的后续处理,通过直接将请求响应的body内容包装陈对象来简化返回使用。
                例如:
                    RestTemplate restTemplate = new RestTemplate();
                    User user = new User("ld", 20);
                    String postResult = restTemplate.postForObject("http[://USER-SERVICE/user", user, String.class);
    
                三个重载方法:
    
                    postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
                    
                    postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
                    
                    postForObject(URI url, Object request, Class<T> responseType)
    
            --第三种:postForLocation()函数
                
                解析:该函数实现了以post请求提交资源,并放回新资源的URI
                例如:
                    User user = new User("ld", 40);
                    URI responseUri = restTemplate.postForLocation("http://USER-SERVICE/user", user);
    
                三个重载方法:
                   
                    postForLocation(String url, Object request, Object... uriVariables)
                    
                    postForLocation(String url, Object request, Map<String, ?> uriVariables)    
                    
                    postForLocation(URI url, Object request)
                    
                    解析:由于postForLocation函数会返回新资源的URI,该URI就相当于指定了放回类型,所以此方法实现的post请求不需
                         要像postforEntity和postForObject一样执行responseType。
                         其他参数用法相同
    
    -Put请求
    
        在RestTemplate中,对PUT请求可以通过put方法进行调用实现
        例如:
            RestTemplate restTemplate = new RestTemplate();
            Long id = 100L;
            User user = new User("ld", 40);
            restTemplate.put("http://USER-SERVICE/user/{1}", user, id);
        
        解析:put函数返回类型为void类型,所以没有返回内容,也就没有其他函数定义的responseType参数,除此之外的其他传入参数定义和
            用法与postForObject基本一致。
    
    -Delete请求
    
        在RestTemplate中,对DELETE请求可以通过delete方法进行调用实现
        例如:
            RestTemplate restTemplate = new RestTemplate();
            Long id = 100L;
            restTemplate.delete("http://USER-SERVICE/user/{1}",id);
    
        三个重载方法:
            
            delete(String url, Object... urlVariables)
            
            delete(String url, Map urlVariables)
            
            delete(URI uri)
        
        解析:由于我们在进行REST请求时,通常都将delete请求的唯一标识拼接在url中,所以delete请求也不需要requestType的body信
             息,就如上面三个函数一样,非常简单。
             url指定delete请求的位置,urlVariable绑定url中的参数即可。
    

    以上是转载

    RestTemplate 的配置项

    1)setBufferRequestBody 是否是否缓冲流来存储请求体,默认true
    
    2)setProxy 设置代理对象
    
    3)setChunkSize 设置每次传输字节长度,与 setBufferRequestBody(false)结合使用
    
    4)setConnectTimeout 设置连接超时时间,默认 -1
    
    5)setReadTimeout 设置读取内容超时时间,默认 -1
    
    6)setOutputStreaming 设置Connection是否设置输出流程
    
    7)setTaskExecutor 设置异步回调执行器
    
  • 相关阅读:
    第八场 hdu 6136 Death Podracing(dfs+思维)
    第九场 hdu 6162 Ch’s gift(树链剖分+线段树)
    树链剖分 模板
    CodeForces
    第十场 hdu 6172 Array Challenge(矩阵快速幂)
    第十场 hdu 6171 Admiral(双向bfs找交点)
    CodeForces
    第十场 hdu 6178 (bfs)
    第十场 hdu 6180 Schedule (multiset)/(思维)
    第八场 hdu 6143 Killer Names(思维题)
  • 原文地址:https://www.cnblogs.com/loveer/p/12002739.html
Copyright © 2020-2023  润新知