1.待解决问题
针对用户上传JSON数组中的每一条JSON报出具体错误,并在前端展示给用户。
2.定义传递信息的对象
这里我定义了两个对象
Message对象:
@Data
public class Message {//一条查询和一次insert事务的结果
int re;//查询or上传数据是否成功 1成功 2失败
String mes;//告知用户的错误信息
}
CZJG对象
@Data
public class CZJG {//用户进行一次输入JSON数组的提交,整体的结果
int state;//1插入全部正确,2有错误,3查询成功
List<Message> messages;
}
3.考虑各种可能会出现的错误
3.1JSON数组的格式不正确
这时利用阿里提供的String转为JSONArray的方法时,会抛出异常,使用try catch捕获这个异常,并在catch中记录这个错误。
//string转为JSONArray
try{//格式不正确,返回false操作失败
jsonArray = JSONArray.fromObject(text);
}catch (JSONException e){
e.printStackTrace();
result.setRe(2);
result.setMes("JSON数组格式有误!");
results.add(result);
czjg.setState(2);
czjg.setMessages(results);
return czjg;
}
3.2用户编写JSON串不符合申请给出的JSON串编写规则
@Override
public int chushihua(String text, int aid){
this.application_id = aid;
//通过aid查找到pid
int pid = applicationMapper.findPidByAid(aid);
UserJson userJson = JSONObject.parseObject(text,UserJson.class);
//先验证密钥是否正确,通过aid得到数据库中秘钥。
String keyByAid = applicationPlusMapper.findKeyByAid(aid);
String miyao = userJson.getKey();
if(!keyByAid.equals(miyao)){
return 0;
}
//先验证dbname,通过发布id查询pinfo得到的英文名是否与用户输入的相同。
String dbname = userJson.getDbname();
String dbname1 = publishMapper.findPublishById(pid).getDbname();
if(!Objects.equals(dbname, dbname1)){
return 0;
}else {
this.dbname = publishMapper.findPublishById(pid).getDbname();
}
//再验证表名是否正确。
String name = dbname+"_"+pid;//拼接形成表名
List<String> chartnames = pDetailMapper.findChartnames(name);
List<String> chartsname = userJson.getChartsname();
List<String> temp = new ArrayList<>(chartnames);
temp.removeAll(chartsname);
if(!temp.isEmpty()){
return 0;
}else {
this.chartnames1 = chartnames;
}
chartnames2 = new ArrayList<>();
for (String chartname : chartnames) {
List<PDetail> byChartname = pDetailMapper.findByChartname(name, chartname);
chartnames2.add(byChartname);
}
//根据类型type
if(userJson.getType().equals("insert")){
return 1;
}else if(userJson.getType().equals("select")){
return 2;
}else {//type输入不合规定
return 0;
}
}
else {//有误
result.setRe(2);
result.setMes("JSON串("+i_text+")不符合申请要求格式!");
results.add(result);
}
3.3缺失要求上传的字段数据
对于JSON的meta部分,用户可能犯得编写错误是,漏了某个表的某个字段,漏了某个表的所有字段。
对于漏写了某个表,使用jsonObject.getJSONObject(pDetail.getChartname())方法时返回的是一个空指针,不能调用get(pDetail.getMeta()),所以这时会抛出异常,捕获这个异常以记录这个错误。
try{
o = jsonObject.getJSONObject(pDetail.getChartname()).get(pDetail.getMeta());
}catch (NullPointerException e){
System.out.println("=======");
result.setRe(2);
result.setMes("JSON串("+text+")缺失要求上传的字段");
return result;
}
对于漏写了某个表的某个字段,调用 o = jsonObject.getJSONObject(pDetail.getChartname()).get(pDetail.getMeta());方法就因为漏写了字段而返回一个空对象。
if(o == null){
result.setRe(2);
result.setMes("JSON串("+text+")缺失要求上传的字段");
return result;
}
3.4SQL语句执行错误
捕获异常后就可以记录错误。
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//创建连接
conn = DriverManager.getConnection(jdbcUrl,"root","jiamohan@599");
// String sql = "INSERT INTO "+name+" ("+metas+") VALUES ("+values+")";
//设置事务不自动提交
conn.setAutoCommit(false);
//把想要一次性提交的几个sql语句用事务进行提交
stmt = conn.createStatement();
for (String sql : sqls) {
stmt.executeUpdate(sql);
}
conn.commit(); //使用commit提交事务
} catch (Exception e){
e.printStackTrace();
//捕获异常,进行数据的回滚
try {
assert conn != null;
conn.rollback();
//把事务再改成自动提交(默认状态)
conn.setAutoCommit(true);
}catch (SQLException exception){
exception.printStackTrace();
}
result.setRe(2);
result.setMes("执行insert操作失败!");
return result;
}
4.前端实现
前端使用弹框表格向用户展示错误:
<el-dialog title="错误信息" :visible.sync="dialogVisible2" width="50%">
<el-table
:data="messages"
border
style="width: 100%">
<el-table-column
type="index"
label="序号"
width="50">
</el-table-column>
<el-table-column
prop="mes"
label="错误信息">
</el-table-column>
</el-table>
</el-dialog>
5.前后端交互实现
根据response.data.state的数值,做出不同响应。
upload(){
let params=new URLSearchParams()
params.append('text',this.textarea)
params.append('aid',this.application_id)
let _this = this;
axios.post(`api/uploadData`,params).then(function (response) {
if(response.data.state === 1){
_this.$message({
type: 'success',
message: '上传数据成功!'
});
}else if (response.data.state === 2){//弹出弹出框,框中含有
_this.dialogVisible2 = true;
_this.messages = response.data.messages;
}else {
_this.dialogVisible = true;
}
})
},