Why -from Java- JSON returns this error? Clearly is in the JSON deserialization, but I cannot find exactly where it occurs

huangapple go评论68阅读模式
英文:

Why -from Java- JSON returns this error? Clearly is in the JSON deserialization, but I cannot find exactly where it occurs

问题

情况:
[![从 Postman,JSON 正确返回数据][1]][1]
[1]: https://i.stack.imgur.com/4Kk0J.png

服务器端:
允许读取所有位于 /api/articulos 下的请求体。

Router router = Router.router(vertx);
router.route("/api/articulos*").handler(BodyHandler.create());
router.get("/api/articulos/:cantcomp1/:cantcomp2/:tipoprod/:prodpadre").handler(bizArticulo::getOneReadingBarcode);

业务

private static final String SELECT_CBA = "select art.leyenda, $1 :: numeric as cantidad, uni.abreviatura, "
+ "round(((art.precio_costo * (art.utilidad_fraccionado/100)) + art.precio_costo) * ($2),2) as totpagar "
+ "FROM public.articulos art join public.unidades uni on uni.idunidad = art.idunidad "
+ "WHERE (substring(art.codigobarra,1,2) = ($3) and substring(art.codigobarra,3,6) = ($4))";
public void getOneReadingBarcode(RoutingContext routingContext) {
		Double cantComprada1 = Double.parseDouble(routingContext.request().getParam("cantcomp1"));
		Double cantComprada2 = Double.parseDouble(routingContext.request().getParam("cantcomp2"));
		String tipoProducto = routingContext.request().getParam("tipoprod");
		String productoPadre = routingContext.request().getParam("prodpadre");

		HttpServerResponse response = routingContext.response();

		pgClient
		.preparedQuery(SELECT_CBA)
		.execute(Tuple.of(cantComprada1, cantComprada2, tipoProducto, productoPadre), ar -> {
			if (ar.succeeded()) {

				RowSet<Row> rows = ar.result(); // 始终返回一个文章

				List<Articulo> articulos = new ArrayList<>();
				rows.forEach(row -> {
					articulos.add(fromBarCode(row));
				});

				response.putHeader("content-type", "application/json; charset=utf-8")
				.setStatusCode(200)
				.end(Json.encodePrettily(articulos));
			} else {
				System.out.println("失败:" + ar.cause().getMessage());
				response.putHeader("content-type", "application/json; charset=utf-8")
				.end(Json.encodePrettily(ar.cause().getMessage()));
			}
		});
	}
private static Articulo fromBarCode(Row row) {
		String leyenda = row.getString("leyenda");
		BigDecimal cantComprada = row.getBigDecimal("cantidad");
		String abreviatura = row.getString("abreviatura");
		BigDecimal total_a_pagar = row.getBigDecimal("totpagar");

		Articulo articulo = new Articulo();

		articulo.setLeyenda(leyenda);
		articulo.setCant_comprada(cantComprada);
		articulo.setAbreviatura(abreviatura);
		articulo.setTot_a_pagar(total_a_pagar);
		return articulo;
	}

客户端

private void validarArticulo() {
		switch (txtCodigoBarra.getText().substring(0,2)) {

		case "20":
			Integer d = Integer.parseInt(txtCodigoBarra.getText().substring(8, 12));
			Double decimal = d * 0.001; // 转换为千克

			System.out.println(
					String.format("%.3f", decimal) + " | " +
					String.format("%.3f", decimal) + " | " +
					txtCodigoBarra.getText().substring(0, 2)  + " | " +
					txtCodigoBarra.getText().substring(2, 8)
					);
		
			PosAccess
			.getCodigoBarra(
					decimal,
					decimal,
					txtCodigoBarra.getText().substring(0, 2),
					txtCodigoBarra.getText().substring(2, 8));
		case "77":

		}
}
public static ObservableList<Articulo> getCodigoBarra(Double cantComp1, Double cantComp2, String tipoProducto, String productoPadre) {
		ObservableList<Articulo> itemsArticulo = FXCollections.observableArrayList();

		WebClient client = WebClient.create(Vertx.vertx());
		client
		.get(PORT, HOST, "/api/conceptos/" + cantComp1 + "/" + cantComp2 + "/" + tipoProducto + "/" + productoPadre)
		.send(ar -> {
			if (ar.succeeded()) {
				HttpResponse<Buffer> response = ar.result();
		
				response.bodyAsJsonArray().forEach(articulo -> {
					JsonObject jo = (JsonObject) articulo;
					itemsArticulo.add(new Articulo(jo.getString("leyenda"), jo.getDouble("cant_comprada"), jo.getString("abreviatura"), jo.getDouble("tot_a_pagar")));					
				});				
				
				System.out.println("收到状态码为 " + response.statusCode());
				System.out.println(response.bodyAsJsonArray());
			} else {
				System.out.println("发生错误:" + ar.cause().getMessage());
			}
		});
		return itemsArticulo;
	}

好的,这是代码。当扫描条形码时,我收到这个错误

0,750 | 0,750 | 20 | 021162
oct. 11, 2020 6:33:18 A. M. io.vertx.core.impl.ContextImpl
SEVERE: 未处理的异常
io.vertx.core.json.DecodeException: 解码失败意外字符 ('<' (代码 60))预期有效值 (JSON 字符串数字数组对象或令牌 'null'、'true''false')
[: (io.netty.buffer.ByteBufInputStream);: 1,: 2]
	at io.vertx.core.json.jackson.JacksonCodec.fromParser(JacksonCodec.java:100)
	at io.vertx.core.json.jackson.JacksonCodec.fromBuffer(JacksonCodec.java:67)
	at io.vertx.ext.web.codec.impl.BodyCodecImpl.lambda$static$2(BodyCodecImpl.java:51)
	at io.vertx.ext.web.client.impl.HttpResponseImpl.bodyAsJsonArray(HttpResponseImpl.java:116)
	at consumer.PosAccess.lambda$0(PosAccess.java:45)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: com.fasterxml.jackson.core.JsonParseException: 意外字符 ('<' (代码 60))预期有效值 (JSON 字符串数字数组对象或令牌 'null'、'true''false')
[: (io.netty.buffer.ByteBufInputStream);: 1,: 2

<details>
<summary>英文:</summary>

**Situation:** 
[![from Postman, JSON returns the data correctly][1]][1]
  [1]: https://i.stack.imgur.com/4Kk0J.png

**Server side:**
Enables the reading of the request body for all routes under /api/articulos.

Router router = Router.router(vertx);
router.route("/api/articulos*").handler(BodyHandler.create());
router.get("/api/articulos/:cantcomp1/:cantcomp2/:tipoprod/:prodpadre").handler(bizArticulo::getOneReadingBarcode);

*Business*

private static final String SELECT_CBA = "select art.leyenda, $1 :: numeric as cantidad, uni.abreviatura, "

  • "round(((art.precio_costo * (art.utilidad_fraccionado/100)) + art.precio_costo) * ($2),2) as totpagar "
  • "FROM public.articulos art join public.unidades uni on uni.idunidad = art.idunidad "
  • "WHERE (substring(art.codigobarra,1,2) = ($3) and substring(art.codigobarra,3,6) = ($4))";

public void getOneReadingBarcode(RoutingContext routingContext) {
Double cantComprada1 = Double.parseDouble(routingContext.request().getParam("cantcomp1"));
Double cantComprada2 = Double.parseDouble(routingContext.request().getParam("cantcomp2"));
String tipoProducto = routingContext.request().getParam("tipoprod");
String productoPadre = routingContext.request().getParam("prodpadre");

	HttpServerResponse response = routingContext.response();
pgClient
.preparedQuery(SELECT_CBA)
.execute(Tuple.of(cantComprada1, cantComprada2, tipoProducto, productoPadre), ar -&gt; {
if (ar.succeeded()) {
RowSet&lt;Row&gt; rows = ar.result(); // return always ONE ARTICLE
List&lt;Articulo&gt; articulos = new ArrayList&lt;&gt;();
rows.forEach(row -&gt; {
articulos.add(fromBarCode(row));
});
response.putHeader(&quot;content-type&quot;, &quot;application/json; charset=utf-8&quot;)
.setStatusCode(200)
.end(Json.encodePrettily(articulos));
} else {
System.out.println(&quot;Failure: &quot; + ar.cause().getMessage());
response.putHeader(&quot;content-type&quot;, &quot;application/json; charset=utf-8&quot;)
.end(Json.encodePrettily(ar.cause().getMessage()));
}
});
}

private static Articulo fromBarCode(Row row) {
String leyenda = row.getString("leyenda");
BigDecimal cantComprada = row.getBigDecimal("cantidad");
String abreviatura = row.getString("abreviatura");
BigDecimal total_a_pagar = row.getBigDecimal("totpagar");

	Articulo articulo = new Articulo();
articulo.setLeyenda(leyenda);
articulo.setCant_comprada(cantComprada);
articulo.setAbreviatura(abreviatura);
articulo.setTot_a_pagar(total_a_pagar);
return articulo;
}
**Client-side**

private void validarArticulo() {
switch (txtCodigoBarra.getText().substring(0,2)) {

	case &quot;20&quot;:
Integer d = Integer.parseInt(txtCodigoBarra.getText().substring(8, 12));
Double decimal = d * 0.001; // convert to kilos
System.out.println(
String.format(&quot;%.3f&quot;, decimal) + &quot; | &quot; +
String.format(&quot;%.3f&quot;, decimal) + &quot; | &quot; +
txtCodigoBarra.getText().substring(0, 2)  + &quot; | &quot; +
txtCodigoBarra.getText().substring(2, 8)
);
PosAccess
.getCodigoBarra(
decimal,
decimal,
txtCodigoBarra.getText().substring(0, 2),
txtCodigoBarra.getText().substring(2, 8));
case &quot;77&quot;:
}

public static ObservableList<Articulo> getCodigoBarra(Double cantComp1, Double cantComp2, String tipoProducto, String productoPadre) {
ObservableList<Articulo> itemsArticulo = FXCollections.observableArrayList();

	WebClient client = WebClient.create(Vertx.vertx());
client
.get(PORT, HOST, &quot;/api/conceptos/&quot; + cantComp1 + &quot;/&quot; + cantComp2 + &quot;/&quot; + tipoProducto + &quot;/&quot; + productoPadre)

// .get(PORT, HOST, "/api/conceptos/")
// .setQueryParam("cantcomp1", cantComp1)
// .addQueryParam("cantcomp2", cantComp2)
// .addQueryParam("tipoproducto", tipoProducto)
// .addQueryParam("productopadre", productoPadre)
.send(ar -> {
if (ar.succeeded()) {
HttpResponse<Buffer> response = ar.result();

			response.bodyAsJsonArray().forEach(articulo -&gt; {
JsonObject jo = (JsonObject) articulo;
itemsArticulo.add(new Articulo(jo.getString(&quot;leyenda&quot;), jo.getDouble(&quot;cant_comprada&quot;), jo.getString(&quot;abreviatura&quot;), jo.getDouble(&quot;tot_a_pagar&quot;)));					
});				
System.out.println(&quot;Received response with status code &quot; + response.statusCode());
System.out.println(response.bodyAsJsonArray());
} else {
System.out.println(&quot;Something went wrong &quot; + ar.cause().getMessage());
}
});
return itemsArticulo;
}
**Ok, that&#39;s the code. When scan the barcode I get this error**

0,750 | 0,750 | 20 | 021162
oct. 11, 2020 6:33:18 A. M. io.vertx.core.impl.ContextImpl
SEVERE: Unhandled exception
io.vertx.core.json.DecodeException: Failed to decode:Unexpected character ('<' (code 60)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 2]
at io.vertx.core.json.jackson.JacksonCodec.fromParser(JacksonCodec.java:100)
at io.vertx.core.json.jackson.JacksonCodec.fromBuffer(JacksonCodec.java:67)
at io.vertx.ext.web.codec.impl.BodyCodecImpl.lambda$static$2(BodyCodecImpl.java:51)
at io.vertx.ext.web.client.impl.HttpResponseImpl.bodyAsJsonArray(HttpResponseImpl.java:116)
at consumer.PosAccess.lambda$0(PosAccess.java:45)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 2]
... 22 more

Anyboy can help me?
TIA
Ernesto
</details>
# 答案1
**得分**: 1
你正在调用错误的端点(即 `/api/conceptos/` 而不是 `/api/articulos`)。
&lt;br&gt;
&lt;br&gt;
在帖子中提供的截图中,展示了一个正确的响应,显示了一个针对以下URL的响应:
192.168.0.15:8092/api/articulos/0.75/0.75/20/021162
但在你的代码中,却有如下部分:
client.get(PORT, HOST, &quot;/api/conceptos/&quot; + cantComp1 + &quot;/&quot; + cantComp2 + &quot;/&quot; + tipoProducto + &quot;/&quot; + productoPadre)
<details>
<summary>英文:</summary>
You are calling the wrong endpoint (i.e. `/api/conceptos/` instead of `/api/articulos`).
&lt;br&gt;
&lt;br&gt;
In the screenshot provided in the post, which illustrates a correct response, you are showing a response for url
192.168.0.15:8092/api/articulos/0.75/0.75/20/021162
but in the code you have
client.get(PORT, HOST, &quot;/api/conceptos/&quot; + cantComp1 + &quot;/&quot; + cantComp2 + &quot;/&quot; + tipoProducto + &quot;/&quot; + productoPadre)
</details>
# 答案2
**得分**: 0
根据我的经验,这个错误消息通常出现在你尝试将API响应反序列化为JSON时,但实际响应内容类似于:
```html
<html><body><h1>Resource not found</h1></body></html>

或者

<html><body><h1>Internal server error</h1></body></html>

并且在第一个字符&lt;处解析失败。

对于你的情况,这可能发生在response.bodyAsJsonArray()处。

请为你调用的URL创建一个调试输出:

String url = "/api/conceptos/" + cantComp1 + "/" + cantComp2 + "/" + tipoProducto + "/" + productoPadre;
英文:

According to my experiences, this error message:

io.vertx.core.json.DecodeException: Failed to decode:Unexpected character (&#39;&lt;&#39; 

usualy happens when you try to deserialize an api response into a json, but indeed the response is something like:

&lt;html&gt;&lt;body&gt;&lt;h1&gt;Resource not found&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;

or

&lt;html&gt;&lt;body&gt;&lt;h1&gt;Internal server error&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;

and the parsing fails at the first char &lt;

For your case, this happens at response.bodyAsJsonArray() probably.

please make a debug output for the url what you are calling:

String url = &quot;/api/conceptos/&quot; + cantComp1 + &quot;/&quot; + cantComp2 + &quot;/&quot; + tipoProducto + &quot;/&quot; + productoPadre;

huangapple
  • 本文由 发表于 2020年10月11日 17:56:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64302726.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定