当前位置: 首页 > wzjs >正文

cms建站流程seoul是什么意思

cms建站流程,seoul是什么意思,青海企业网站建设开发,微信app下载链接问题描述 业务需要调用一个第三方图像识别的API,然后将识别出来的结果区分出不同类型,并分别装配到对应的Java实体类里 听起来是一个很正常的需求,现在JSON解析的工具有很多,而且都很成熟,但奈何识别出的JSON结果嵌套…

问题描述

业务需要调用一个第三方图像识别的API,然后将识别出来的结果区分出不同类型,并分别装配到对应的Java实体类里

听起来是一个很正常的需求,现在JSON解析的工具有很多,而且都很成熟,但奈何识别出的JSON结果嵌套了很多复杂的结构,找不到现成的工具方法解决这个问题,JSON格式如下所示:

{"words_result": [{"result": {"AmountInWords": [{"word": "贰佰圆整"}],"InvoiceNumConfirm": [{"word": "8xxxxx13"}],// ================================省略n行// ****************************************"CommodityPrice": [{"row": "1","word": "7.1238475"}],"CommodityNum": [{"row": "1","word": "24.8447205"}],"CommodityTaxRate": [{"row": "1","word": "13%"}],"InvoiceCode": [{"word": "0xxxxx611"}],"AmountInFiguers": [{"word": "200.00"}],"CommodityAmount": [{"row": "1","word": "176.99"}],"CommodityType": [{"row": "1","word": "92号"}],"CommodityTax": [{"row": "1","word": "23.01"}],"CommodityUnit": [{"row": "1","word": "升"}],"CommodityName": [{"row": "1","word": "*汽油*92号车用汽油(VIB)"}],"InvoiceNum": [{"word": "8xxxxx3"}]},"top": 0,"left": 0,"probability": 0.9595113397,"width": 845,"type": "vat_invoice","height": 544}],"words_result_num": 1,"pdf_file_size": 1,"log_id": "1xxxxxxxxxxxx8"
}

因此我需要手动设计JSON解析的方法

问题分析

因为需要根据不同的识别结果种类,装配到不同的实体类中,并且可能会灵活增加或删除种类,所以需要设计一套易于拓展,方便开发的的方案

根据这样的业务场景,我决定使用工厂模式的策略模式来实现,创建一个总的接口类,子类都实现该接口类,并且使用Java的反射机制,解析实体类的属性,和JSON识别结果的参数名进行一一查找对应,然后可以使用注解来标注类属性名和参数名的映射关系

这样可以实现通用的,易于拓展的代码,需要改变参数值或增加减少识别种类,只需要改变实体类属性本身,不需要改变装配代码

(原JSON中参数名下带"row"字段的,需要额外放到实体类下货品类数组中,row代表第几行的index,和实体类本身是父子关系)

问题解决

接口枚举类样例
// 接口类
public interface Invoice {String getInvoiceNum();String getAmount();
}// 字段映射注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InvoiceJsonField {String value();
}// 识别种类枚举
public enum InvoiceTypeEnum {VAT_INVOICE("vat_invoice"),TICKET_INVOICE("ticket_invoice");private String typeCode;InvoiceTypeEnum(String typeCode) {this.typeCode = typeCode;}public String getTypeCode() {return typeCode;}public void setTypeCode(String typeCode) {this.typeCode = typeCode;}
}
实体类样例
// 实体类种类1-实现接口Invoice
@Data
public class VatInvoice implements Invoice {private String invoiceNum;private String invoiceCode;private List<CommodityInfo> commodityList;  // 货品list// 属性名与参数名不一致,同注解写明映射关系@InvoiceJsonField("AmountInFiguers")private String amount;private String amountInWords;
}// 实体类种类2-实现接口Invoice
@Data
public class TicketInvoice implements Invoice {@InvoiceJsonField("ticketNum")private String invoiceNum;private String invoiceName;@InvoiceJsonField("AmountInFiguers")private String ticketAmount;private String amountInWords;
}// 货品类,JSON中带"row"字段的属性,row代表第几行的index
@Data
public class CommodityInfo implements Serializable {@InvoiceJsonField("commodityName")private String name; //货物名称@InvoiceJsonField("commodityType")private String type;//规格型号@InvoiceJsonField("commodityUnit")private String unit;//单位@InvoiceJsonField("commodityNum")private String num;//数量@InvoiceJsonField("commodityPrice")private String price;//单价@InvoiceJsonField("commodityAmount")private String amount;//金额@InvoiceJsonField("commodityTaxRate")private String taxRate;//税率@InvoiceJsonField("commodityTax")private String tax;//税额
}
工厂类

parseInvoice() 方法构造目标对象

public class InvoiceFactory {public static Invoice parseInvoice(JSONObject resObject) throws JsonProcessingException, IllegalAccessException {ObjectMapper objectMapper = new ObjectMapper();JsonNode rootNode = objectMapper.readTree(resObject.toString());String type = rootNode.get("words_result").get(0).get("type").asText();JsonNode wordsResultNode = rootNode.get("words_result").get(0).get("result");Invoice invoice;Boolean isCommodity = false;if (type.equals(InvoiceTypeEnum.VAT_INVOICE.getTypeCode())){invoice = new VatInvoice();isCommodity = true;}else if (type.equals(InvoiceTypeEnum.TICKET_INVOICE.getTypeCode())){invoice = new TicketInvoice();}else{//===加新的类只需要在这加,类实现Invoice接口,添加枚举种类,类属性名和接口返回值属性名一致,驼峰命名首字母小写============throw new RuntimeException();  // 可改为自定义异常抛错}return parseInvoice(invoice, wordsResultNode,isCommodity);}private static Invoice parseInvoice(Invoice invoice, JsonNode wordsResultNode, Boolean isCommodity) throws IllegalAccessException {List<CommodityInfo> infoList = new ArrayList<>();// 反射机制-解析类Class<?> clazz = invoice.getClass();Field[] fields = clazz.getDeclaredFields();Iterator<Map.Entry<String, JsonNode>> fieldsIterator = wordsResultNode.fields();while (fieldsIterator.hasNext()) {// 遍历参数与实体类Map.Entry<String, JsonNode> jsonField = fieldsIterator.next();String jsonKey = jsonField.getKey();JsonNode jsonValue = jsonField.getValue();String javaFieldName = toLowerCaseCamelCase(jsonKey);if (isCommodity){// 装配List<CommodityInfo>setCommodity(infoList,javaFieldName,jsonValue);}// 装配一般字段setFieldValueFor(fields, invoice, jsonValue, javaFieldName);}if (isCommodity){for (Field field : fields) {if (field.getName().equals("commodityList")){field.setAccessible(true);field.set(invoice,infoList);}}}return invoice;}// 装配List<CommodityInfo>private static void setCommodity(List<CommodityInfo> commodity,String javaFieldName,JsonNode jsonValue){JsonNode jsonNode = jsonValue.get(0);if(jsonNode != null && jsonNode.get("row") != null){Integer index = jsonNode.get("row").asInt() - 1;if (commodity.size()<index+1){CommodityInfo commodityInfo = new CommodityInfo();setFieldValueFor(CommodityInfo.class.getDeclaredFields(),commodityInfo,jsonNode,javaFieldName);commodity.add(index,commodityInfo);}else{setFieldValueFor(CommodityInfo.class.getDeclaredFields(),commodity.get(index),jsonNode,javaFieldName);}}}// 属性名驼峰转换private static String toLowerCaseCamelCase(String str) {if (str == null || str.isEmpty()) {return str;}StringBuilder result = new StringBuilder();boolean capitalizeNext = false;for (char c : str.toCharArray()) {if (c == '_') {capitalizeNext = true;} else {if (capitalizeNext) {result.append(Character.toUpperCase(c));capitalizeNext = false;} else {result.append(c);}}}str = result.toString();return Character.toLowerCase(str.charAt(0)) + str.substring(1);}// 反射机制给实体类set值private static void setFieldValueFor(Field[] fields, Object object, JsonNode jsonValue, String jsonFieldName) {for (Field field : fields) {InvoiceJsonField annotation = field.getAnnotation(InvoiceJsonField.class);// 如果有注解映射关系,优先寻找,没有则默认按属性名走boolean shouldMap = (annotation != null && toLowerCaseCamelCase(annotation.value()).equals(jsonFieldName)) ||(annotation == null && field.getName().equals(jsonFieldName));if (shouldMap) {try {// 设置字段值Object value = parseFieldValue(field.getType(), jsonValue);field.setAccessible(true);if (value.getClass().isAssignableFrom(String.class)){field.set(object, value);}else{field.set(object, ((TextNode)value).textValue());}} catch (IllegalAccessException e) {e.printStackTrace();}}}}// 设置字段值private static Object parseFieldValue(Class<?> fieldType, JsonNode jsonValue) {if (jsonValue == null || jsonValue.isNull()) {return null;}// 去掉word这一层级,手动放值if (fieldType.isArray()) {ArrayNode arrayNode = (ArrayNode) jsonValue;List<String> list = new ArrayList<>();for (JsonNode item : arrayNode) {list.add(String.valueOf(item.get("word").asText()));}return list.toArray(new String[0]);}if (fieldType.isAssignableFrom(String.class)) {if (jsonValue.get("word")!=null){return jsonValue.get("word").asText();}else{ArrayNode arrayNode = (ArrayNode) jsonValue;String builder = "";if (arrayNode.isEmpty()){return "";}else{builder = builder + arrayNode.get(0).get("word").asText();for (int i = 1; i < arrayNode.size(); i++) {builder = builder + ",";builder = builder + arrayNode.get(i).get("word").asText();}}return builder.toString();}}return null;}}

结果测试

对于问题描述中给出的识别JSON样例,进行解析测试

public class Main {// 测试demopublic static void main(String[] args) {String testJson = "..........";		// 省略jsontry {Invoice invoice = InvoiceFactory.parseInvoice(JSONObject.parseObject(testJson));System.out.println(invoice);} catch (JsonProcessingException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}
}

测试打印结果,可以看到属性值都已经正确放到实体类中了

VatInvoice(invoiceNum=8xxxxx3, invoiceCode=0xxxxx611, commodityList=[CommodityInfo(name=*汽油*92号车用汽油(VIB), type=92, unit=, num=24.8447205, price=7.1238475, amount=176.99, taxRate=13%, tax=23.01)], amount=200.00, amountInWords=贰佰圆整)
http://www.dtcms.com/wzjs/247766.html

相关文章:

  • 蓟州农家院如何做网站网络营销策划与创意
  • 完整网页开发水平优化
  • 网站建设与制作课后题答案平台推广怎么做
  • 建设银行jo 办网站用卡杭州seo网站建设靠谱
  • 广州建站客服招聘国内搜索引擎
  • 网站制作案例如何网络推广具体内容
  • 西安做网站优化宁波seo网络推广定制多少钱
  • 东莞58同城做网站电话快速学电脑培训班
  • wordpress qq客服seo优化的内容有哪些
  • icp备案查看网站内容吗什么平台可以免费推广产品
  • 淄博市网站建设百搜网络科技有限公司
  • 如东建设网站广西南宁做网站的公司
  • 仿牌做独立网站可靠吗浏览器网站进入口
  • 江苏公司网站建设百度查一下
  • 无锡专业做网站广州seo顾问
  • 网站建设客户来源网络销售平台有哪些软件
  • 我想去澳大利亚做按摩找哪个网站sem分析
  • 企业网站设计要求厦门seo招聘
  • 网站制作 呼和浩特成都网站搜索排名优化公司
  • 协会网站建站新闻热点大事件
  • 怎样做自己的网络平台杭州明开seo
  • 手机wap网站怎么做广州谷歌推广
  • 动态ip怎么建设网站培训心得体会500字
  • lol视频网站模板seo黑帽技术有哪些
  • 网站免费申请注册seo中介平台
  • 大型网站建设设备网站推广优化外包便宜
  • 做个中英文网站多少钱营销案例最新
  • 动易网站频道栏目字体大小修改2022适合小学生的简短新闻
  • 网站建设税率英文seo是什么意思
  • 无忧主机建站的过程长沙网站建设