AAS10对应用web.xml的校验配置

本文介绍了在AASV10中遇到的web.xml文件部署错误,问题源于web.xml中标签库顺序不符合标准。解决方法包括调整web.xml的标签顺序或更改XML验证选项。XML验证提供了三种模式:完全(报错不部署)、解析(报错后继续部署)和无(不报错继续部署)。调整后,应用成功部署。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AASV10默认是对应用的描述文件web.xml是做严格的规范检测的,如果文件内容有问题,如标签库的顺序没有符合标准,部署时会报错,但是能够通过设置,对web.xml不校验或者检验后给出错误提示但是继续部署。

问题:部署某个应用报如下错误
Exception during lifecycle processing java.io.IOException: org.xml.sax.SAXParseException; lineNumber: 57; columnNumber: 11; Deployment descriptor file WEB-INF/web.xml in archive [report]. 元素类型为 "web-app" 的内容必须匹配

"(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping

*,listener*,servlet*,servlet-mapping*,session-config?,mime-mapping*,welcome-file-list?, error-page*,taglib*,resource-env-ref*,resource-ref*,security-constraint*,login-config?, security-role*,env-entry*,ejb-ref*,ejb-local-ref*)"。
原因分析:

可能是web.xml 标签库顺序问题 在后面部署报错,调整到 在前面部署成功。

解决方法

应用程序设置中可以对 web 应用描述文件 web.xml 解析方式进行设置,默认为“完全”,当 web.xml 文件里面的标签库的顺序不对时,会报错并且不进行部署。

XML 验证选项说明:

· 1.完全:报错并且不部署失败。

· 2.解析:报告错误,继续部署。

· 3.无:不报告错误,继续部署。

在这里插入图片描述

@PostMapping(value = "/compare") public R compare(@RequestPart("File") MultipartFile file, @RequestPart("jsonContent") String jsonContent) { //读取PDF文本 String pdfText = compareService.extractContent(file); //解析JSON配置 JsonNode jsonConfig = null; try { jsonConfig = compareService.parseJson(jsonContent); } catch (Exception e) { return R.fail(MessageUtils.message("failed.convert.json")); } //执行对比校验 List<ValidationResult> results = compareService.compareContent(pdfText, jsonConfig); //返回没有匹配成功的数据 List<ValidationResult> failedResults = new ArrayList<>(); for (ValidationResult result : results) { if (!result.isValid()) { failedResults.add(result); } } if (failedResults.isEmpty()) { return R.ok("条件符合规范"); } else { return R.ok(failedResults); } }package com.example.demo.config; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.accept.ContentNegotiationManagerFactoryBean; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // ObjectMapper objectMapper = JsonMapper.builder() MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); jsonConverter.setObjectMapper(new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)); jsonConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, new MediaType("application", "*+json"))); MappingJackson2XmlHttpMessageConverter xmlConverter = new MappingJackson2XmlHttpMessageConverter(); xmlConverter.setObjectMapper(new XmlMapper().setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)); xmlConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XML, new MediaType("application", "*+xml"))); converters.add(jsonConverter); converters.add(xmlConverter); } @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer .mediaType("json", MediaType.APPLICATION_JSON) .mediaType("xml", MediaType.APPLICATION_XML); } @Bean public ContentNegotiationManager contentNegotiationManager() { ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean(); factory.setDefaultContentType(MediaType.APPLICATION_JSON); factory.setFavorParameter(true); factory.setParameterName("format"); factory.setIgnoreAcceptHeader(true); factory.setUseRegisteredExtensionsOnly(true); Map<String, MediaType> mediaTypes = new HashMap<>(); mediaTypes.put("json", MediaType.APPLICATION_JSON); mediaTypes.put("xml", MediaType.APPLICATION_XML); factory.addMediaTypes(mediaTypes); return factory.getObject(); } } package com.luxsan.domain; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * 校验结果封装类 */ @Data @AllArgsConstructor @NoArgsConstructor @JacksonXmlRootElement(localName = "validationResult") public class ValidationResult { @JsonProperty("checkType") private String checkType; // 检查类型: FIELD/REGEX/NUMERIC @JsonProperty("fieldName") private String fieldName; // 字段名 @JsonProperty("expected") private String expected; // 预期值 @JsonProperty("actual") private String actual; // 实际值 @JsonProperty("valid") private boolean valid; // 是否通过 } package com.luxsan.service; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.hankcs.hanlp.HanLP; import com.hankcs.hanlp.seg.common.Term; import com.luxsan.common.core.utils.MessageUtils; import com.luxsan.domain.ValidationResult; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import net.sourceforge.tess4j.Tesseract; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.*; @RequiredArgsConstructor @Service public class ReadFileContentService { private final ObjectMapper objectMapper = new ObjectMapper(); private final XmlMapper xmlMapper = new XmlMapper(); private Tesseract tesseract; @PostConstruct public void initOcrEngine() { tesseract = new Tesseract(); try { //语言包路径和支持语言 tesseract.setDatapath("D:\\maven_use\\lingxi-lhc\\lingxi-ai-extend\\lingxi-ai-comparison\\src\\main\\resources\\tessdata"); tesseract.setLanguage("eng+chi_sim"); tesseract.setPageSegMode(6); // 自动页面分割 tesseract.setOcrEngineMode(1); // LSTM引擎 } catch (Exception e) { throw new RuntimeException("OCR引擎初始化失败: " + e.getMessage(), e); } } /** * 支持PDF和图片 */ public String extractContent(MultipartFile file) { String contentType = file.getContentType(); String fileName = file.getOriginalFilename().toLowerCase(); if (contentType == null) { return "不支持的文件类型: " + contentType; } if (fileName.endsWith(".pdf")) { return readPdfText(file); } return extractImageText(file); } /** * 读取PDF文本内容 * * @param file * @return */ public String readPdfText(MultipartFile file) { try (PDDocument doc = PDDocument.load(file.getInputStream())) { PDFTextStripper stripper = new PDFTextStripper(); // 设置行分隔符 stripper.setLineSeparator("\n"); // 设置字符间距 stripper.setSortByPosition(true); String rawText = stripper.getText(doc); System.out.println("内容" + rawText); return rawText.trim(); } catch (Exception e) { return MessageUtils.message("file.red.pdf.error"); } } /** * OCR识别图片内容 */ private String extractImageText(MultipartFile file) { try { // 创建临时文件 Path tempFile = Files.createTempFile("ocr_", getFileExtension(file.getOriginalFilename())); Files.copy(file.getInputStream(), tempFile, StandardCopyOption.REPLACE_EXISTING); // 执行OCR识别 File imageFile = tempFile.toFile(); String result = tesseract.doOCR(imageFile) .replaceAll("\\s+", " ").trim(); System.out.println("读取的内容" + result); // 清理临时文件 Files.deleteIfExists(tempFile); return result; } catch (Exception e) { return "OCR处理失败: " + e.getMessage(); } } private String getFileExtension(String filename) { if (filename == null) return ".tmp"; int dotIndex = filename.lastIndexOf('.'); return (dotIndex == -1) ? ".tmp" : filename.substring(dotIndex); } public JsonNode parseJson(String jsonContent) throws Exception { // return this.objectMapper.readTree(jsonContent); try { // 尝试解析 JSON return objectMapper.readTree(jsonContent); } catch (Exception e) { try { // 尝试解析 XML return xmlMapper.readTree(jsonContent); } catch (Exception ex) { throw new Exception("Failed to parse JSON or XML", ex); } } } public List<ValidationResult> compareContent(String pdfText, JsonNode jsonConfig) { List<ValidationResult> results = new ArrayList<>(); // 去除读取内容中的多余空格 pdfText = pdfText.replaceAll("\\s+", ""); // 处理JSON结构(支持单个对象或数组) JsonNode dataNode; if (jsonConfig.isArray() && jsonConfig.size() > 0) { dataNode = jsonConfig.get(0); } else if (jsonConfig.isObject()) { dataNode = jsonConfig; } else { results.add(new ValidationResult("ERROR", "JSON格式错误", "期望一个对象或包含对象的数组", "实际格式不匹配", false)); return results; } // 动态定义地址字段列表 Set<String> addressFields = new HashSet<>(); Iterator<String> fieldNames = dataNode.fieldNames(); while (fieldNames.hasNext()) { String fieldName = fieldNames.next(); if (fieldName.contains("CITY") || fieldName.contains("STATE") || fieldName.contains("ZIP")) { addressFields.add(fieldName); } } // 字段直接匹配 checkNonAddressFields(pdfText, dataNode, results, addressFields); // 连续匹配 checkAddressFields(pdfText, dataNode, results, addressFields); return results; } /** * 检查 JSON 中非地址字段是否严格存在于 PDF 文本中 */ private void checkNonAddressFields(String pdfText, JsonNode jsonConfig, List<ValidationResult> results, Set<String> addressFields) { Iterator<Map.Entry<String, JsonNode>> fields = jsonConfig.fields(); while (fields.hasNext()) { Map.Entry<String, JsonNode> entry = fields.next(); String fieldName = entry.getKey(); JsonNode valueNode = entry.getValue(); if (valueNode.isValueNode() && !addressFields.contains(fieldName)) { //去除多余空格 String expectedValue = valueNode.asText().trim().replaceAll("\\s+", ""); if (expectedValue.isEmpty()) continue; // 直接进行字符串匹配 boolean found = pdfText.contains(expectedValue); results.add(new ValidationResult( "FIELD", fieldName, expectedValue, found ? "Found" : "Not Found", found )); } } } /** * 检查 JSON 中地址字段是否严格存在于 PDF 文本中 */ private void checkAddressFields(String pdfText, JsonNode jsonConfig, List<ValidationResult> results, Set<String> addressFields) { // HanLP分词 List<Term> terms = HanLP.segment(pdfText); List<String> addressParts = new ArrayList<>(); for (Term term : terms) { String word = term.word; if (word.matches("\\d{5,7}")) { addressParts.add(word); } else if (term.nature.toString().startsWith("ns")) { addressParts.add(word); } } // 遍历 JSON 配置中的地址字段 Iterator<Map.Entry<String, JsonNode>> fields = jsonConfig.fields(); while (fields.hasNext()) { Map.Entry<String, JsonNode> entry = fields.next(); String fieldName = entry.getKey(); JsonNode valueNode = entry.getValue(); if (valueNode.isValueNode() && addressFields.contains(fieldName)) { //去除多余空格 String expectedValue = valueNode.asText().trim().replaceAll("\\s+", ""); if (expectedValue.isEmpty()) continue; boolean found = false; for (String part : addressParts) { if (part.equals(expectedValue)) { found = true; break; } } results.add(new ValidationResult( "FIELD", fieldName, expectedValue, found ? "Found" : "Not Found", found )); } } } } 我的方法 我的结果我选择json的时候结果是对的 然后我选择xml的时候 结果还是json
最新发布
07-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值