将Http请求转换为RabbitMQ消息

Filter

import com.google.common.base.Charsets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RestTemplate;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static com.onlyedu.maindata.Constant.LISTENER_URL_PREFIX;

/**
 * @author qbit
 */
@Slf4j
@Component
public class SinkToRabbitmq implements Filter {
	//我们约定所有接收消息的api的url格式为/${LISTENER_URL_PREFIX}/${exchange}/${topic}
	private static final String LISTENER_URL_PREFIX="/listener/";
	//对于get请求同步转发给后端swagger服务,这样可以对外显示文档(但是无法调用)
    private static final String SWAGGER_ADDRESS="http://swagger:8080";
    private final RestTemplate restTemplate=new RestTemplate();
    private final AmqpTemplate amqpTemplate;
    //对于所有请求均返回成功
    private static final String SUCCESS = "SUCCESS ";

    public SinkToRabbitmq(AmqpTemplate amqpTemplate) {
        this.amqpTemplate = amqpTemplate;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response=(HttpServletResponse)servletResponse;
        String uri = request.getRequestURI();
        if (!uri.startsWith(LISTENER_URL_PREFIX)) {
            var repositoryResponse=restTemplate.getForEntity(SWAGGER_ADDRESS+uri,String.class);
            response.setStatus(repositoryResponse.getStatusCodeValue());
            try (ServletOutputStream os = servletResponse.getOutputStream()) {
                os.write(repositoryResponse.getBody().getBytes(Charsets.UTF_8));
            }
        } else {
            String body = StreamUtils.copyToString(request.getInputStream(), Charsets.UTF_8);
            //记录下日志用于自己重放请求
            log.info("curl -X " + request.getMethod() + " --header 'Content-Type: application/json' --header 'Accept: */*' -d '" + body.replaceAll("\r|\n", " ") + "' 'http://localhost:8080" + uri + "'");
            var after= StringUtils.substringAfter(uri,LISTENER_URL_PREFIX);
            var exchange=StringUtils.substringBefore(after,"/");
            var topic = StringUtils.substringAfterLast(after,  "/");
            amqpTemplate.convertAndSend(exchange, topic, body);
            servletResponse.setCharacterEncoding(Charsets.UTF_8.toString());
            servletResponse.setContentType("application/json;charset=utf-8");
            try (ServletOutputStream os = servletResponse.getOutputStream()) {
                os.write(SUCCESS.getBytes(Charsets.UTF_8));
            }
        }
    }
}

MessageConverter

由于我们发送的消息是json格式的string而不是对象,所以需要自定义序列化,将json格式String原样所为payload

@Bean
    @Primary
    public MessageConverter messageConverter(){
        return new MessageConverter() {
            @Override
            public Message toMessage(Object object, MessageProperties messageProperties){
                messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
                return new Message(object.toString().getBytes(Charsets.UTF_8),messageProperties);
            }

            @Override
            public Object fromMessage(Message message) throws MessageConversionException {
                throw new UnsupportedOperationException();
            }
        };
    }

exchange

虽然上面是根据uri来判断发向哪个exchange,但是最好能明确exchang从而自动创建

@Bean
    TopicExchange exchange(){
        return ExchangeBuilder.topicExchange(EXCHANGE).durable(true).build();
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值