com.fasterxml.jackson.core.JsonParseException:意外字符(';\';(代码92))[Java]

com.fasterxml.jackson.core.JsonParseException:意外字符(';\';(代码92))[Java],java,json,string,parsing,jackson,Java,Json,String,Parsing,Jackson,我为这个混乱的标题深感抱歉,但我完全不明白为什么会发生这种情况 我正在尝试使用Jackson解析JSON字符串。我的代码很简单: import com.fasterxml.jackson.databind.ObjectMapper; import formatter.Tweet; import com.fasterxml.jackson.databind.DeserializationFeature; public class FormatterTester { static String

我为这个混乱的标题深感抱歉,但我完全不明白为什么会发生这种情况

我正在尝试使用Jackson解析JSON字符串。我的代码很简单:

import com.fasterxml.jackson.databind.ObjectMapper;
import formatter.Tweet;
import com.fasterxml.jackson.databind.DeserializationFeature;
public class FormatterTester {


static String tweet = "{\"created_at\":\"Fri May 03 11:43:17 +0000 2019\",\"id\":1124278249620566017,\"id_str\":\"1124278249620566017\",\"text\":\"RT @entkom: '\\u0e40\\u0e0b\\u0e49\\u0e19\\u0e15\\u0e4c-\\u0e28\\u0e38\\u0e20\\u0e1e\\u0e07\\u0e29\\u0e4c' \\u0e41\\u0e08\\u0e01\\u0e04\\u0e27\\u0e32\\u0e21\\u0e19\\u0e48\\u0e32\\u0e23\\u0e31\\u0e01 \\u0e21\\u0e2d\\u0e1a\\u0e04\\u0e27\\u0e32\\u0e21\\u0e2a\\u0e38\\u0e02\\u0e43\\u0e2b\\u0e49\\u0e41\\u0e1f\\u0e19\\u0e04\\u0e25\\u0e31\\u0e1a https:\\/\\/t.co\\/hBbi5hzEH8\",\"source\":\"\\u003ca href=\\\"http:\\/\\/twitter.com\\/download\\/android\\\" rel=\\\"nofollow\\\"\\u003eTwitter for Android\\u003c\\/a\\u003e\",\"truncated\":false,\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":1062336001941504001,\"id_str\":\"1062336001941504001\",\"name\":\"\\ud83d\\udc0a\\u26bd\\ud83d\\udc2f\\ud83c\\udfb8\\ud83d\\udc99sugajin\\/\\/\\ud83d\\udc9a\\ud83d\\udc7b\\ud83d\\udc32\\ud83d\\udc0a\",\"screen_name\":\"sugajinBTS1\",\"location\":null,\"url\":null,\"description\":\"#BTS\\u597d\\u304d\\ud83d\\udc95\\u30b8\\u30f3\\u30cb\\u30e0\\u3088\\u308a\\u306e\\uff75\\uff99\\uff8d\\uff9f\\uff9d\\n#LGBTQ\\u304c\\u3082\\u3063\\u3068\\u7406\\u89e3\\u3055\\u308c\\u3066\\u6b32\\u3057\\u3044\\n#lovebychance\\u306e\\u6cbc\\u306b\\u30cf\\u30de\\u308a\\u4e2d\\n#season2\\u3068\\u3063\\u3066\\u3082\\u671f\\u5f85\\uff01\\uff01\\n#PinSon\\u2665SonPin\\n#2wish\\ud83d\\udc99\\ud83d\\udc9a\\n#Magus\\n#TeamReal\\n#LBCForever\\n\\u7121\\u8a00\\u30d5\\u30a9\\u30ed\\u30fc\\u5931\\u793c\\u3057\\u307e\\u3059\\ud83d\\ude47\",\"translator_type\":\"none\",\"protected\":false,\"verified\":false,\"followers_count\":61,\"friends_count\":224,\"listed_count\":0,\"favourites_count\":37785,\"statuses_count\":11611,\"created_at\":\"Tue Nov 13 13:26:54 +0000 2018\",\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":false,\"lang\":\"ja\",\"contributors_enabled\":false,\"is_translator\":false,\"profile_background_color\":\"F5F8FA\",\"profile_background_image_url\":\"\",\"profile_background_image_url_https\":\"\",\"profile_background_tile\":false,\"profile_link_color\":\"1DA1F2\",\"profile_sidebar_border_color\":\"C0DEED\",\"profile_sidebar_fill_color\":\"DDEEF6\",\"profile_text_color\":\"333333\",\"profile_use_background_image\":true,\"profile_image_url\":\"http:\\/\\/pbs.twimg.com\\/profile_images\\/1062337509701513216\\/5HFkKxoi_normal.jpg\",\"profile_image_url_https\":\"https:\\/\\/pbs.twimg.com\\/profile_images\\/1062337509701513216\\/5HFkKxoi_normal.jpg\",\"profile_banner_url\":\"https:\\/\\/pbs.twimg.com\\/profile_banners\\/1062336001941504001\\/1543643861\",\"default_profile\":true,\"default_profile_image\":false,\"following\":null,\"follow_request_sent\":null,\"notifications\":null},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"retweeted_status\":{\"created_at\":\"Fri May 03 01:29:52 +0000 2019\",\"id\":1124123879654301696,\"id_str\":\"1124123879654301696\",\"text\":\"'\\u0e40\\u0e0b\\u0e49\\u0e19\\u0e15\\u0e4c-\\u0e28\\u0e38\\u0e20\\u0e1e\\u0e07\\u0e29\\u0e4c' \\u0e41\\u0e08\\u0e01\\u0e04\\u0e27\\u0e32\\u0e21\\u0e19\\u0e48\\u0e32\\u0e23\\u0e31\\u0e01 \\u0e21\\u0e2d\\u0e1a\\u0e04\\u0e27\\u0e32\\u0e21\\u0e2a\\u0e38\\u0e02\\u0e43\\u0e2b\\u0e49\\u0e41\\u0e1f\\u0e19\\u0e04\\u0e25\\u0e31\\u0e1a https:\\/\\/t.co\\/hBbi5hzEH8\",\"source\":\"\\u003ca href=\\\"http:\\/\\/twitter.com\\\" rel=\\\"nofollow\\\"\\u003eTwitter Web Client\\u003c\\/a\\u003e\",\"truncated\":false,\"in_reply_to_status_id\":null,\"in_reply_to_status_id_str\":null,\"in_reply_to_user_id\":null,\"in_reply_to_user_id_str\":null,\"in_reply_to_screen_name\":null,\"user\":{\"id\":69565234,\"id_str\":\"69565234\",\"name\":\"ent_komchadluek\",\"screen_name\":\"entkom\",\"location\":null,\"url\":null,\"description\":null,\"translator_type\":\"none\",\"protected\":false,\"verified\":false,\"followers_count\":6684,\"friends_count\":1115,\"listed_count\":86,\"favourites_count\":14,\"statuses_count\":31813,\"created_at\":\"Fri Aug 28 11:28:17 +0000 2009\",\"utc_offset\":null,\"time_zone\":null,\"geo_enabled\":false,\"lang\":\"en\",\"contributors_enabled\":false,\"is_translator\":false,\"profile_background_color\":\"FF6699\",\"profile_background_image_url\":\"http:\\/\\/abs.twimg.com\\/images\\/themes\\/theme11\\/bg.gif\",\"profile_background_image_url_https\":\"https:\\/\\/abs.twimg.com\\/images\\/themes\\/theme11\\/bg.gif\",\"profile_background_tile\":true,\"profile_link_color\":\"B40B43\",\"profile_sidebar_border_color\":\"CC3366\",\"profile_sidebar_fill_color\":\"E5507E\",\"profile_text_color\":\"362720\",\"profile_use_background_image\":true,\"profile_image_url\":\"http:\\/\\/pbs.twimg.com\\/profile_images\\/471687167\\/ent1_normal.jpg\",\"profile_image_url_https\":\"https:\\/\\/pbs.twimg.com\\/profile_images\\/471687167\\/ent1_normal.jpg\",\"default_profile\":false,\"default_profile_image\":false,\"following\":null,\"follow_request_sent\":null,\"notifications\":null},\"geo\":null,\"coordinates\":null,\"place\":null,\"contributors\":null,\"is_quote_status\":false,\"quote_count\":9,\"reply_count\":33,\"retweet_count\":584,\"favorite_count\":505,\"entities\":{\"hashtags\":[],\"urls\":[{\"url\":\"https:\\/\\/t.co\\/hBbi5hzEH8\",\"expanded_url\":\"http:\\/\\/www.komchadluek.net\\/news\\/ent\\/370511#.XMuZj_HCjrY.twitter\",\"display_url\":\"komchadluek.net\\/news\\/ent\\/37051\\u2026\",\"indices\":[52,75]}],\"user_mentions\":[],\"symbols\":[]},\"favorited\":false,\"retweeted\":false,\"possibly_sensitive\":false,\"filter_level\":\"low\",\"lang\":\"th\"},\"is_quote_status\":false,\"quote_count\":0,\"reply_count\":0,\"retweet_count\":0,\"favorite_count\":0,\"entities\":{\"hashtags\":[],\"urls\":[{\"url\":\"https:\\/\\/t.co\\/hBbi5hzEH8\",\"expanded_url\":\"http:\\/\\/www.komchadluek.net\\/news\\/ent\\/370511#.XMuZj_HCjrY.twitter\",\"display_url\":\"komchadluek.net\\/news\\/ent\\/37051\\u2026\",\"indices\":[64,87]}],\"user_mentions\":[{\"screen_name\":\"entkom\",\"name\":\"ent_komchadluek\",\"id\":69565234,\"id_str\":\"69565234\",\"indices\":[3,10]}],\"symbols\":[]},\"favorited\":false,\"retweeted\":false,\"possibly_sensitive\":false,\"filter_level\":\"low\",\"lang\":\"th\",\"timestamp_ms\":\"1556883797446\"}";

public static void main(String[]args) {

    String valor_retorno= null;
    Tweet tw;

    try {

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        tw = objectMapper.readValue(tweet, Tweet.class);

        System.out.println("Check 3 - El formatter retorna:\n"+tw.toString());

        valor_retorno = tw.toString();
    }  catch (Exception e) {
        e.printStackTrace();
        System.out.println("\nException " + e.getClass() + ": " + e.getMessage());
    } finally {
        System.out.println("\nReturn: Valor_retorno = "+valor_retorno);
    }

}
} 如果你运行代码,你会发现它工作得很好。那么问题出在哪里呢?我必须在Oracle NoSQL数据库上执行相同的操作。了解与数据检索相关的任何部分都不重要,因为它们工作得很好,我已经对它们进行了测试。代码非常相似:

String data = new String(value.toByteArray(),StandardCharsets.UTF_8);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
tw = objectMapper.readValue(data, Tweet.class);
我的目标是获得与第一个代码完全相同的结果。根据我的类Tweet的属性,由“|”分隔的值字符串

然而,这段代码被压缩在一个Jar文件中,并由数据库在所有记录的tweet上内部运行。我无法看到发生了什么,也无法调试它,但它会产生以下异常:

com.fasterxml.jackson.core.JsonParseException:非法字符((CTRL-CHAR,代码0)):令牌之间只允许有规则的空白(\r\n\t)

我尝试用
StringEscapeUtils.escapeJava(data)跳过字符串“data”
然后会产生以下异常:

com.fasterxml.jackson.core.JsonParseException:意外字符('\'(代码92)):应为有效值(数字、字符串、数组、对象、“true”、“false”或“null”) 我还尝试过像下面这样跳过字符串
data.replace(“\”)没有成功


经过多次测试后,我无法理解为什么它在我首先放在这里的演示上运行良好,而不是在实际项目上运行良好,具有完全相同的依赖项。

出于某种原因,Jackson无法解析我从数据库中检索到的内容。这很可能是因为我的Docker容器用来存放DB的CentOS中存在编码或去编码问题,脚本是在那里被调用和执行的

最后,使用Gson进行解析是最好的选择,尽管如果不修剪()字符串,仍然会产生错误。显然,出于某种原因,JSON被引用了两次。这是“JSON文本”

守则:

package formatter;

import java.io.*;
import java.lang.String;
import java.nio.charset.StandardCharsets;
import java.util.List;

import oracle.kv.*;
import com.google.gson.Gson;
import oracle.kv.KeyValueVersion;
import oracle.kv.exttab.Formatter;

public class TweetFormatter implements Formatter {

    public TweetFormatter() {
        super();
    }

    public String toOracleLoaderFormat(final KeyValueVersion kvv, final KVStore kvStore){

        String valor_retorno= null;

        Tweet tw; //antes sin null

        BufferedWriter bf = FormatterUtils.getInstance().getWriter();

        try {
            final Key key = kvv.getKey();
            final Value value = kvv.getValue();
            Value.Format format = value.getFormat();

            FormatterUtils.getInstance().writeLine(bf,"[Key: "+ key + ", Value:" +value.toByteArray()+ "]" + ". Format= "+ format.toString());

            //Filtrar Clave
            List<String> major = key.getMajorPath();

            FormatterUtils.getInstance().writeLine(bf,"Check 1:\n Key is: "+key + "\n Key length is: "+major.size()
                    + "\n Values are: "+major.toString() + "\n contains: "+major.contains("TweeterStream"));

            Boolean contains = false;

            for(String x : major) {
                if(x.equals("TweeterStream")||x.equals("/TweeterStream")||x.equals("/TweeterStream/")) {
                    contains = true;
                    break;
                }
            }

            //Parsear
            if(contains){

                String data = new String(value.toByteArray(),StandardCharsets.UTF_8);

                data = data.trim();
                tw = new Gson().fromJson(data,Tweet.class); //FUNCIONA

                FormatterUtils.getInstance().writeLine(bf,"Check 3 - El formatter retorna:\n"+tw.toString());
                valor_retorno = tw.toString();
            }else{
                FormatterUtils.getInstance().writeLine(bf,"\nEstoy en else");
            }
            FormatterUtils.getInstance().writeLine(bf,"\nestoy fuera del if-else");
        }  catch (Exception e) {
            e.printStackTrace();
            FormatterUtils.getInstance().writeLine(bf, "\nException " + e.getClass() + ": " + e.getMessage());
        } finally {
            FormatterUtils.getInstance().writeLine(bf,"\nReturn: Valor_retorno = "+valor_retorno);
            FormatterUtils.getInstance().generateLog(bf);
        }
        return valor_retorno;
    }
包格式化程序;
导入java.io.*;
导入java.lang.String;
导入java.nio.charset.StandardCharset;
导入java.util.List;
导入oracle.kv.*;
导入com.google.gson.gson;
导入oracle.kv.KeyValueVersion;
导入oracle.kv.exttab.Formatter;
公共类TweetFormatter实现格式化程序{
公共TweetFormatter(){
超级();
}
公共字符串toOracleLoaderFormat(最终键值版本kvv,最终KVStore KVStore){
字符串valor_returno=null;
Tweet tw;//antes sin null
BufferedWriter bf=FormatterUtils.getInstance().getWriter();
试一试{
final Key=kvv.getKey();
最终值=kvv.getValue();
Value.Format Format=Value.getFormat();
FormatterUtils.getInstance().writeLine(bf,“[Key:+Key+”,Value:“+Value.toByteArray()+”]“+”。Format=“+Format.toString());
//过滤板
List major=key.getMajorPath();
FormatterUtils.getInstance().writeLine(bf,“检查1:\n键为:“+Key+”\n键长度为:“+major.size())
+“\n值为:“+major.toString()+”\n contains:“+major.contains”(“TweeterStream”);
布尔包含=假;
用于(字符串x:主要){
if(x.equals(“TweeterStream”)| | x.equals(“/TweeterStream”)| | x.equals(“/TweeterStream/”){
包含=真;
打破
}
}
//帕塞尔
如果(包含){
字符串数据=新字符串(value.toByteArray(),StandardCharsets.UTF_8);
data=data.trim();
tw=new Gson().fromJson(数据,Tweet.class);//函数a
FormatterUtils.getInstance().writeLine(bf,“检查3-El格式化程序returna:\n”+tw.toString());
valor_retrono=tw.toString();
}否则{
FormatterUtils.getInstance().writeLine(bf,“\nEstoy en else”);
}
FormatterUtils.getInstance().writeLine(bf,“\nestoy fuera del if else”);
}捕获(例外e){
e、 printStackTrace();
FormatterUtils.getInstance().writeLine(bf,“\nException”+e.getClass()+”:“+e.getMessage());
}最后{
FormatterUtils.getInstance().writeLine(bf,“\n返回:Valor_returno=“+Valor_returno”);
FormatterUtils.getInstance().generateLog(bf);
}
返回勇气号;
}

由于某些原因,Jackson无法解析我从数据库中检索到的内容。这很可能是因为我的Docker容器用于保存数据库的CentOS中存在编码或反编码问题,以及脚本的调用和执行位置

最后,使用Gson进行解析是最好的选择,尽管如果不修剪()字符串,仍然会产生错误。显然,出于某种原因,JSON引用了两次。这是“JSON文本”

守则:

package formatter;

import java.io.*;
import java.lang.String;
import java.nio.charset.StandardCharsets;
import java.util.List;

import oracle.kv.*;
import com.google.gson.Gson;
import oracle.kv.KeyValueVersion;
import oracle.kv.exttab.Formatter;

public class TweetFormatter implements Formatter {

    public TweetFormatter() {
        super();
    }

    public String toOracleLoaderFormat(final KeyValueVersion kvv, final KVStore kvStore){

        String valor_retorno= null;

        Tweet tw; //antes sin null

        BufferedWriter bf = FormatterUtils.getInstance().getWriter();

        try {
            final Key key = kvv.getKey();
            final Value value = kvv.getValue();
            Value.Format format = value.getFormat();

            FormatterUtils.getInstance().writeLine(bf,"[Key: "+ key + ", Value:" +value.toByteArray()+ "]" + ". Format= "+ format.toString());

            //Filtrar Clave
            List<String> major = key.getMajorPath();

            FormatterUtils.getInstance().writeLine(bf,"Check 1:\n Key is: "+key + "\n Key length is: "+major.size()
                    + "\n Values are: "+major.toString() + "\n contains: "+major.contains("TweeterStream"));

            Boolean contains = false;

            for(String x : major) {
                if(x.equals("TweeterStream")||x.equals("/TweeterStream")||x.equals("/TweeterStream/")) {
                    contains = true;
                    break;
                }
            }

            //Parsear
            if(contains){

                String data = new String(value.toByteArray(),StandardCharsets.UTF_8);

                data = data.trim();
                tw = new Gson().fromJson(data,Tweet.class); //FUNCIONA

                FormatterUtils.getInstance().writeLine(bf,"Check 3 - El formatter retorna:\n"+tw.toString());
                valor_retorno = tw.toString();
            }else{
                FormatterUtils.getInstance().writeLine(bf,"\nEstoy en else");
            }
            FormatterUtils.getInstance().writeLine(bf,"\nestoy fuera del if-else");
        }  catch (Exception e) {
            e.printStackTrace();
            FormatterUtils.getInstance().writeLine(bf, "\nException " + e.getClass() + ": " + e.getMessage());
        } finally {
            FormatterUtils.getInstance().writeLine(bf,"\nReturn: Valor_retorno = "+valor_retorno);
            FormatterUtils.getInstance().generateLog(bf);
        }
        return valor_retorno;
    }
包格式化程序;
导入java.io.*;
导入java.lang.String;
导入java.nio.charset.StandardCharset;
导入java.util.List;
导入oracle.kv.*;
导入com.google.gson.gson;
导入oracle.kv.KeyValueVersion;
导入oracle.kv.exttab.Formatter;
公共类TweetFormatter实现格式化程序{
公共TweetFormatter(){
超级();
}
公共字符串toOracleLoaderFormat(最终键值版本kvv,最终KVStore KVStore){
字符串valor_returno=null;
Tweet tw;//antes sin null
BufferedWriter bf=FormatterUtils.getInstance().getWriter();
试一试{
final Key=kvv.getKey();
最终值=kvv.getValue();
Value.Format Format=Value.getFormat();
FormatterUtils.getInstance().writeLine(bf,“[Key:+Key+”,Value:“+Value.toByteArray()+”]“+”。Format=“+Format.toString());
//