Spring boot 如何避免\“;在json中';谁的绳子?

Spring boot 如何避免\“;在json中';谁的绳子?,spring-boot,gson,activemq,Spring Boot,Gson,Activemq,Spring启动应用程序 在build.gradle中: implementation 'com.google.code.gson:gson:2.7' 这里是JMS配置: import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.spri

Spring启动应用程序

在build.gradle中:

implementation 'com.google.code.gson:gson:2.7'
这里是JMS配置:

import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
@Configuration
@ComponentScan(basePackages = "ru.otus.software_architect.eshop")
public class JMSConfiguration {

    @Bean
    public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                    DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        // This provides all boot's default to this factory, including the message converter
        configurer.configure(factory, connectionFactory);
        // You could still override some of Boot's default if necessary.
        return factory;
    }

    @Bean
    public MessageConverter jacksonJmsMessageConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }
}
在日志中:

成功\u向\u MB发送消息\u

{"email":"someemail@email.com","action":"order_update","orderId":14}
很好

但在我的队列中的ActiveMQ上,消息如下所示:

  "{\"email\":\"a_subscriber@mail.ru\",\"action\":\"order_update\",\"orderId\":4,\"createdAt\":\"2020-09-13T11:32:09.976+0300\"}"
"%7B%22email%22%3A%22myemail%40mail.com%22%2C%22action%22%3A%22order_delete%22%2C%22orderId%22%3A6%2C%22createdAt%22%3A%222020-09-19T12%3A20%3A57.844%2B0300%22%7D"
这里是截图:

然后启动另一个应用程序(消费者)。当尝试从json获取日期时,它被破坏:

JsonElement messageJson = GsonUtil.parser.parse(message);
String action = messageJson.getAsJsonObject().get("action").getAsString(); // here broken
我收到错误消息:

Caused by: java.lang.IllegalStateException: Not a JSON Object: "{\"email\":\"a_subscriber@mail.ru\",\"action\":\"order_update\",\"orderId\":4,\"createdAt\":\"2020-09-13T11:32:09.976+0300\"}"
如何避免字符串中的\

我需要排队成为下一个字符串:

{"email":"someemail@email.com","action":"order_update","orderId":14}

尝试使用默认的
MessageConverter
(即),并以
字节[]
的形式发送消息,例如:

private void sendMessageToMessageBroker(NotifyActionEnum操作,int orderId){
JsonObject json=新的JsonObject();
json.addProperty(“email”,UserService.getCurrentUserName());
addProperty(“action”,action.name().toLowerCase());
addProperty(“orderId”,orderId);
JmsTemplate JmsTemplate=context.getBean(JmsTemplate.class);
String message=json.toString();
convertAndSend(ESHOP_队列,message.getBytes());
info(“sendMessageToMessageBroker:success\u sent\u message\u to\u MB:+message”);
}
当您以
字节[]
的形式发送消息时,
SimpleMessageConverter
将其转换为
javax.jms.ByteMessage
。当您的消费者收到消息时,它可以将
字节[]
转换为
字符串,如下所示:

String消息字符串;
if(字节消息的消息实例){
BytesMessage BytesMessage=(BytesMessage)消息;
byte[]buffer=新字节[(int)bytesMessage.getBodyLength()];
bytesMessage.readBytes(缓冲区);
messageAsString=新字符串(缓冲区);
}
JsonElement messageJson=GsonUtil.parser.parse(messageAsString);
String action=messageJson.getAsJsonObject().get(“action”).getAsString();

我相信以
字节[]
的形式发送消息将避免任何不必要的转义。

我使用
urlEncode/decode
将消息发送到ActiveMQ

在我的控制器中:

private String publishToMessageBroker(NotifyActionEnum action, int orderId) {
        logger.info("publishToMessageBroker:");
        JsonObject json = new JsonObject();
        json.addProperty("email", UserService.getCurrentUserName());
        json.addProperty("action", action.name().toLowerCase());
        json.addProperty("orderId", orderId);
        json.addProperty("createdAt", DateUtil.date2String(new Date(), DateUtil.JSON_DATE_FORMAT));
        String message = json.toString();
        String urlEncodeMessage = StringUtll.urlEncode(message);
        jmsTemplate.convertAndSend(ESHOP_QUEUE, urlEncodeMessage);
        logger.info("publishToMessageBroker: success_sent_message_to_MB: " + message);
        return "Message was success published on Message Broker!"; // can use as response
}
现在在ActiveMQ中,消息如下所示:

  "{\"email\":\"a_subscriber@mail.ru\",\"action\":\"order_update\",\"orderId\":4,\"createdAt\":\"2020-09-13T11:32:09.976+0300\"}"
"%7B%22email%22%3A%22myemail%40mail.com%22%2C%22action%22%3A%22order_delete%22%2C%22orderId%22%3A6%2C%22createdAt%22%3A%222020-09-19T12%3A20%3A57.844%2B0300%22%7D"
现在在信息接收器中,我解码信息

 @JmsListener(destination = ESHOP_QUEUE)
    public void receiveMessage(String urlEncodeMessage) {
        try {
            String urlDecodeMessage = StringUtil.urlDecode(urlEncodeMessage);
            String pureDecodeMessage = StringUtil.removeFirstAndLastQuotes(urlDecodeMessage);
            JsonElement messageJson = GsonUtil.parser.parse(pureDecodeMessage);
现在工作正常。没有像这样的越狱符号

url解码后,我得到纯json:

"{"email":"myemail@mail.com","action":"order_delete","orderId":6,"createdAt":"2020-09-19T12:20:57.844+0300"}"

有东西将字符串放在双引号中,需要转义字符串中的双引号才能起作用。@Steve为什么在队列中用\“?我猜是因为字符串开头和结尾的引号。不管是什么机制添加这些引号,也可以通过在每个字符串前面加“\”来避开字符串中间的引号。我不知道为什么会发生这种情况。您为
JmsTemplate
配置了什么
MessageConverter
?您是否使用默认的
SimpleMessageConverter
字符串
转换为
javax.jms.TextMessage
?@JustinBertram我更新了我的帖子是否可以理解制作人通过web控制台发送的内容?我不确定您的意思。我想查看一些信息,如
{“email”:someemail@email.com“,”动作“:“订单更新”、“订单ID”:14}
通过ui工具我不确定ActiveMQ web控制台是否会将
字节[]
解码为
字符串以显示。请记住,消息(甚至文本消息)可以以多种不同的方式进行编码,代理不一定拥有将消息解码为人类可读格式(假设存在这种格式)所需的信息。我相信web控制台无法将字节[]解码为字符串,因为字节[]可以是任何内容。但order_id可能是一条非常有用的信息,应该能够被视为人类的语言