paulwong

#

SPRING INTEGRATION HEADER问题

当SPRING INTEGRATION的流程中从HTTP outboundGateway转成JmsGateway时,会报header的错误,这时就要把相关多余的header移除。

.headerFilter("Api-Key", "Content-Type", "X-Powered-By", "Content-Language", "Transfer-Encoding", "Cache-Control", "Keep-Alive", "Set-Cookie")

https://stackoverflow.com/questions/50608415/cwsia0112e-the-property-name-keep-alive-is-not-a-valid-java-identifier

posted @ 2020-10-20 14:56 paulwong 阅读(318) | 评论 (0)编辑 收藏

RestTemplate处理请求状态码为非200的返回数据

RestTemplate是Spring提供的用于访问Rest服务的客户端,

RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求,

可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。

ClientHttpRequestFactory接口主要提供了两种实现方式

1、一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。

2、一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。

默认的 RestTemplate 有个机制是请求状态码非200 就抛出异常,会中断接下来的操作。如果不想中断对结果数据得解析,可以通过覆盖默认的 ResponseErrorHandler ,见下面的示例,示例中的方法中基本都是空方法,只要对hasError修改下,让他一直返回true,即是不检查状态码及抛异常了。

package com.example.demo.web.config;

import java.io.IOException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) throws Exception {
        RestTemplate restTemplate = new RestTemplate(factory);
        ResponseErrorHandler responseErrorHandler = new ResponseErrorHandler() {
            @Override
            public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
                return true;
            }
            @Override
            public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
            }
        };
        restTemplate.setErrorHandler(responseErrorHandler);
        return restTemplate;
    }
    
    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        //读取超时5秒
        factory.setReadTimeout(5000);
        //连接超时15秒
        factory.setConnectTimeout(15000);
        return factory;
    }
}

RestTemppate运用实例

package com.example.demo.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.example.demo.domain.Book;

@RestController
public class TestBookController {
    private Logger logger = LoggerFactory.getLogger(getClass());
    
      @Autowired
      private RestTemplate restTemplate;
      
      @GetMapping("/testaddbook")
      public Book testAddBook() {
              Book book = new Book();
              ResponseEntity<Book> responseEntity = restTemplate.postForEntity( "http://localhost:8061/book", book , Book.class);
              return responseEntity.getBody();
      }

}

其他方法,catch HttpStatusCodeException e.getResponseBodyAsString()
try {
    ResponseEntity<Component> response = restTemplate.exchange(webSvcURL,
        HttpMethod.POST, 
        requestEntity,
        Component.class);
catch (HttpStatusCodeException e) {
    List<String> customHeader = e.getResponseHeaders().get("x-app-err-id");
    String svcErrorMessageID = "";
    if (customHeader != null) {
        svcErrorMessageID = customHeader.get(0);                
    }
    throw new CustomException(e.getMessage(), e, svcErrorMessageID);
    // You can get the body too but you will have to deserialize it yourself
    
// e.getResponseBodyAsByteArray()
    
// e.getResponseBodyAsString()
}

https://stackoverflow.com/questions/7878002/resttemplate-handling-response-headers-body-in-exceptions-restclientexception

https://stackoverflow.com/questions/38093388/spring-resttemplate-exception-handling/51805956#51805956

posted @ 2020-10-16 16:54 paulwong 阅读(1143) | 评论 (0)编辑 收藏

Error handling in spring integration - How to get all the errors thrown in multiple threads and send them to the error-channel

在SPRING INTEGRATION中,如果exception发生在各种thread里时,如何将exception返回到指定的channel,之后再绕回到aggrator-channel中。

@Bean
public IntegrationFlow provisionUserFlow() {
return
    IntegrationFlows.from("input.channel")
    .publishSubscribeChannel(Executors.newCachedThreadPool(),
        s -> s.applySequence(true)
            .subscribe(f -> f.enrichHeaders(e -> e.header(MessageHeaders.ERROR_CHANNEL, "errorChannel", true))
                .handle(provisionerA, "provision")
                .channel("aggregatorChannel")
            )
            .subscribe(f -> f.enrichHeaders(e -> e.header(MessageHeaders.ERROR_CHANNEL, "errorChannel", true))
                .handle(provisionerB, "provision")
                .channel("aggregatorChannel"))
            )
        .get();
}

@Bean
public IntegrationFlow aggregateFlow() {
    return IntegrationFlows.from("aggregatorChannel")
                    .channel( aggregatorChannel)
                    .aggregate( a -> a.processor( collect, "aggregatingMethod"))
                    .get();
}

@Transformer( inputChannel = "errorChannel", outputChannel = "aggregatorChannel")
public Message<?> errorChannelHandler(ErrorMessage errorMessage) throws RuntimeException {

    Message<?> failedMessage =  ((MessagingException) errorMessage.getPayload()).getFailedMessage();

    Exception exception = (Exception) errorMessage.getPayload();

    return  MessageBuilder.withPayload( exception.getMessage())
                                       .copyHeadersIfAbsent( failedMessage.getHeaders() )
                                       .build();
}


https://stackoverflow.com/q/46495127/11790720

posted @ 2020-10-15 19:21 paulwong 阅读(230) | 评论 (0)编辑 收藏

SPRING INTEGRATION子FLOW

split-route-aggregate flow 
split之后,可以将message分给不同的子flow处理,配置如下:
@Bean
public IntegrationFlow parallelSplitRouteAggregateFlow() {
    return IntegrationFlows
            .from(Http.inboundGateway("/trigger"))
            .handle((p, h) -> Arrays.asList(1, 2, 3))
            .split()
            .channel(MessageChannels.executor(Executors.newCachedThreadPool()))
            .<Integer, Boolean>route(o -> o % 2 == 0, m -> m
                    .subFlowMapping(true, sf -> sf.gateway(oddFlow()))
                    .subFlowMapping(false, sf -> sf.gateway(evenFlow())))
            .aggregate()
            .get();
}

@Bean
public IntegrationFlow oddFlow() {
    return flow -> flow.<Integer>handle((payload, headers) -> "odd");
}

@Bean
public IntegrationFlow evenFlow() {
    return flow -> flow.<Integer>handle((payload, headers) -> "even");
}


https://stackoverflow.com/questions/50121384/spring-integration-parallel-split-route-aggregate-flow-fails-due-to-one-way-mess

posted @ 2020-10-15 11:29 paulwong 阅读(475) | 评论 (0)编辑 收藏

在LINUX中格式化JSON的工具-jq

安装:
wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
chmod +x ./jq
cp jq /usr/bin

posted @ 2020-10-12 09:55 paulwong 阅读(333) | 评论 (0)编辑 收藏

怀旧框架集合

     摘要: 最近在公司用JUP框架做项目,发现这个框架是别人基于SpringSide封装的,所以打算学习下,SpringSide,其中遇到了很多坑,做个记录,网上关于这方面的资料都有些老了,而且SpringSide最新的版本是SpringSide-Utils,老一点的版本为v4.2.2.GA,以下分别对这两个版本分别介绍下,主要内容来自于网上。一些资料:Github源码地址:  https://gi...  阅读全文

posted @ 2020-10-09 19:14 paulwong 阅读(300) | 评论 (0)编辑 收藏

线上JVM工具

https://github.com/vipshop/vjtools

posted @ 2020-10-09 19:12 paulwong 阅读(248) | 评论 (0)编辑 收藏

基于Spring Cloud的快速开发脚手架&最佳实践总结

Spring Cloud 你懂的
Keycloak 微服务认证授权
Jenkins 持续集成
SonarQube 代码质量控制


https://gitee.com/itmuch/spring-cloud-yes

posted @ 2020-10-09 10:48 paulwong 阅读(535) | 评论 (0)编辑 收藏

Keycloak初探

Keycloak是Jboss出品的做认证和授权的WEB程序,根据OPENIDC协议,OPENID是做认证,OAUTH2.0是做授权,OPENIDC则将这两者整合。

有提供一套WEB界面维护用户、应用与角色。

Ream则可认为是多租户,每个租户的应用和用户数据是隔离的。

http://10.80.27.69:8180/auth/realms/quickstart/.well-known/openid-configuration 提供当前所有的API节点。
get_access_token_from_public_client:
curl --location --request POST 'http://10.80.27.69:8180/auth/realms/quickstart/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=alice' \
--data-urlencode 'password=123456' \
--data-urlencode 'client_id=app-springboot-public' \
--data-urlencode 'grant_type=password' \
| jq

./get_access_token_from_confidential_client.sh
curl --location --request POST 'http://10.80.27.69:8180/auth/realms/quickstart/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=app-springboot-confidential' \
--data-urlencode 'client_secret=3acf7692-49cb-4c45-9943-6f3dba512dae' \
--data-urlencode 'grant_type=client_credentials' \
| jq

访问一个ACCESS TYPE为Bare only的应用的一个API:
access_token=$(curl \
-d "client_id=app-springboot-public" \
-d "username=alice" \
-d "password=123456" \
-d "grant_type=password" \
"http://10.80.27.69:8180/auth/realms/quickstart/protocol/openid-connect/token" \
| jq -r '.access_token')

#echo $access_token

curl -H "Authorization: Bearer $access_token" 'http://10.80.27.69:8182/products' | jq

访问用户信息:
access_token=$(curl \
-d "client_id=app-springboot-public" \
-d "username=alice" \
-d "password=123456" \
-d "grant_type=password" \
"http://10.80.27.69:8180/auth/realms/quickstart/protocol/openid-connect/token" | jq -r '.access_token')


curl -H "Authorization: Bearer $access_token" http://10.80.27.69:8180/auth/realms/quickstart/protocol/openid-connect/userinfo | jq














posted @ 2020-10-08 13:56 paulwong 阅读(714) | 评论 (0)编辑 收藏

配置docker仓库镜像,即使用私服

编辑/etc/docker/daemon.json,加入以下节点:
{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}


posted @ 2020-09-30 15:40 paulwong 阅读(450) | 评论 (0)编辑 收藏

仅列出标题
共110页: First 上一页 8 9 10 11 12 13 14 15 16 下一页 Last