我想使用阻止处理程序,但仍然会收到错误:
java.lang.IllegalStateException: Response has already been written
这是我的代码:
Server.java
r.route("/api/details/send/").handler(BodyHandler.create());
r.route("/api/details/send/").handler(ctx-> {
JsonArray ja = ctx.getBodyAsJsonArray();
JsonArray params = new JsonArray();
vertx.executeBlocking(futur -> {
for(int i =0; i<ja.size();i++) {
JsonObject req = new JsonObject();
req.put("QUERY", "INSERT INTO detailsfacture VALUES ('',?,?,?,?,?,?,?)");
req.put("DB", "MYSQL_");
params.add(ja.getJsonObject(i).getValue("typefacture"))
.add(ja.getJsonObject(i).getValue("activites"))
.add(Integer.parseInt(ja.getJsonObject(i).getValue("qte").toString()))
.add(Double.parseDouble(ja.getJsonObject(i).getValue("pu").toString())
.add(ja.getJsonObject(i).getValue("unite"))
.add(Double.parseDouble(ja.getJsonObject(i).getValue("montant").toString())
.add(ja.getJsonObject(i).getValue("codefacture"));
req.put("PARAMS", params);
eb.send("EXECUTE", req, res -> {
if (res.succeeded()) {
params.clear();
ctx.response().putHeader("content-type", "application/json").end(res.result().body().toString());
} else {
ctx.response().putHeader("content-type", "application/json").end(res.cause().getMessage());
}
});
}
String result = "orsys";
futur.complete(result);
},resultat->{
ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, "text/plain");
//resultat.result().toString();
});
});
MySql.java
eb.consumer("MYSQL_EXECUTE_WITH_PARAMS", req->{
try{
JsonObject reqParams = (JsonObject)req.body();
String sql = reqParams.getString("QUERY");
client.getConnection( connection -> {
if (connection.succeeded()) {
try{
SQLConnection con = connection.result();
con.updateWithParams(sql,reqParams.getJsonArray("PARAMS"), query -> {
if(query.succeeded()){
UpdateResult urs = query.result();
req.reply(urs.toJson());
//req.reply(query.result());
}else{
req.fail(24, "Err Request : "+query.cause().getMessage());
}
});
}catch(Exception e){
req.fail(24, "Err Conn Failed : "+e.getMessage());
}
} else {
req.fail(24, "Err No Connection : "+connection.cause().getMessage());
}
});
}catch(Exception e){
req.fail(24, e.getMessage());
}
});
P.S。 :当我删除executeBlocking时,只有第一个记录在我的数据库中注册。 问候。
答案 0 :(得分:0)
您在循环中将实体插入detailsfacture
。对于每个插入,您可以调用以下内容:
ctx.response().putHeader("content-type", "application/json").end(res.result().body().toString());
如您所见,您调用响应对象的end(...)
方法。那是IllegalStateException
来自哪里。正如documentation所述:
Once the response has ended, it cannot be used any more.
所以你的问题与executeBlocking
无关。
您应该查看HttpServerResponse
的{{3}}方法。对于每个插页,您应拨打write(...)
而不是end(...)
。但这只有在您知道整个响应的完整长度时才有效,因为您需要设置标题Content-length
。如果您已完成所有插入操作,则需要调用end()
来完成响应。此外,您应该只设置一次标题,而不是每次插入。
现在另外一些评论。在您的情况下,我不认为executeBlocking
需要。由于Content-length
存在问题,我建议使用Future
包装每个插页,并使用CompositeFuture
组合所有插页。 Future
futur
的使用方式错误。事件总线的send(...)
方法不是阻塞和异步的。因此,在发送所有插入内容后立即调用futur.complete(result)
。同样奇怪的是consumer
消费MYSQL_EXECUTE_WITH_PARAMS
和send
发送给EXECUTE
。
答案 1 :(得分:0)
我尝试了另一种解决方案来获取我的查询(?,?,...,?),(?,?,...,?),..,(?,?,...,? )。
这是我的代码:
public static String getMultipleInsertReq(String table, JsonArray columns,JsonArray data){
JsonObject tab= Tables.Tables_list.getJsonObject(table); // name of table
String sql = "";
if(tab != null){
sql = "INSERT INTO "+table + "( ";
if(columns == null){
columns = tab.getJsonArray("COLS"); //columns from ur database
}
if(columns!=null){
for(int i=0;i<columns.size();i++){
if(i==columns.size()-1){
sql+=columns.getString(i)+") VALUES";
}
else{
sql+=columns.getString(i)+",";
}
}
for(int i =0; i<data.size();i++){
for(int j=0; j<columns.size();j++){
if(j==columns.size()-1 && i!=data.size()-1){
sql+="?),";
}
else if (i==data.size()-1 && j==columns.size()-1){
sql+="?)";
}
else if (j==0){
sql+="(?,";
}
else{
sql+="?,";
}
}
}
return sql;
}
}
return null;
}
希望它有所帮助。 P.S。:它只是一个查询构建器,因此您可以根据需要进行调整。
问候。