Spring:根据 XSD 架构验证 REST 控制器

2024-07-03

目前我有 RestController 和以下代码

package be.smartask.api;

import be.smartask.api.model.NumberValue;
import be.smartask.api.model.TextValue;
import be.smartask.api.model.Translations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


/**
 * @author Glenn Van Schil
 *         Created on 21/01/2016
 */
@CrossOrigin
@RestController
@RequestMapping(path = "/values")
public class Controller {

    @RequestMapping(method = RequestMethod.POST, headers = "Value-Type=text")
    ResponseEntity<?> createAttribute(@RequestBody TextValue value) {
        System.out.println(value.getCode());
        for (Translations.Translation translation : value.getTranslations().getTranslation()) {
            System.out.println(translation.getLang());
            System.out.println(translation.getValue());
        }
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.POST, headers = "Value-Type=number")
    ResponseEntity<?> createAttribute(@RequestBody NumberValue value) {
        System.out.println(value.getMinValue());
        System.out.println(value.getMaxValue());
        return new ResponseEntity<>(HttpStatus.CREATED);
    }
}

这很好用,我可以发布这样的 NumberValue:

<numberValue id="id" minValue="0" maxValue="10"/>

但是当我发布文本值到数值方法时

<textvalue code="LUXE">
    <translations>
        <translation lang="en">luxury car</translation>
    </translations>
</textvalue>

它仍然有效。它只是将 minValue 和 maxValue 保留为 0,0。

我的问题是:当正文与我的 xsd 文件中定义的不完全相同时,如何强制执行 400: Bad Request (或类似的内容)?根据定义,我的意思是 xml 标记的名称不同或缺少必需的 xs:attribute,...

我的 xsd 文件:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

            <!-- ValueVO -->
    <xs:complexType name="geopoint">
        <xs:attribute type="xs:double" name="lat"/>
        <xs:attribute type="xs:double" name="lon"/>
    </xs:complexType>

    <xs:complexType name="translations">
        <xs:sequence>
            <xs:element name="translation" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="xs:string">
                            <xs:attribute type="xs:string" name="lang" use="required"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="value">
        <xs:attribute type="xs:string" name="id" use="required"/>
    </xs:complexType>

    <xs:complexType name="textValue">
        <xs:complexContent>
            <xs:extension base="value">
                <xs:sequence>
                    <xs:element type="translations" name="translations"/>
                </xs:sequence>
                <xs:attribute type="xs:string" name="code" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="numberValue">
        <xs:complexContent>
            <xs:extension base="value">
                <xs:attribute type="xs:double" name="minValue" use="required"/>
                <xs:attribute type="xs:double" name="maxValue" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="dateValue">
        <xs:complexContent>
            <xs:extension base="value">
                <xs:attribute type="xs:date" name="minValue" use="required"/>
                <xs:attribute type="xs:date" name="maxValue" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="cityValue">
        <xs:complexContent>
            <xs:extension base="value">
                <xs:sequence>
                    <xs:element type="geopoint" name="geopoint"/>
                    <xs:element type="translations" name="translations"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="timeValue">
        <xs:complexContent>
            <xs:extension base="value"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="value" type="value"/>
    <xs:element name="textValue" type="textValue"/>
    <xs:element name="numberValue" type="numberValue"/>
    <xs:element name="dateValue" type="dateValue"/>
    <xs:element name="cityValue" type="cityValue"/>
    <xs:element name="timeValue" type="timeValue"/>

    <xs:element name="values">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="value" maxOccurs="unbounded" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <!-- END ValueVO --> 
</xs:schema>

UPDATE

我根据 Sheetal Mohan Sharma 的回答将以下内容添加到我的 spring 配置中

<?xml version="1.0" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd


http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="be.smartask.api"/>

    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="marshallingHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            </list>
        </property>
    </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    </bean>
    <bean id="marshallingHttpMessageConverter"
          class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"
          p:marshaller-ref="jaxb2Marshaller" p:unmarshaller-ref="jaxb2Marshaller"/>

    <bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="schema" value="classpath:schema/xsd/smartaskRead.xsd"/>
        <property name="classesToBeBound">
            <list>
                <value>be.smartask.api.model.NumberValue</value>
                <value>be.smartask.api.model.TextValue</value>
            </list>
        </property>
    </bean>
</beans>

但 NumberValue 仍然接受 TextValue...


您可以查看使用 jaxb marshaller 和 unmarshaller 使用消息转换器和 jaxmashaller 来检查 XSD。如果验证失败,将抛出错误,但可能不具体。检查下面的链接。

<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"p:marshaller-ref="jaxb2Marshaller" p:unmarshaller-ref="jaxb2Marshaller" />

<bean id="jaxb2Marshaller">
    <property name="schema" value="classpath:/mySchema.xsd"/>
    <property name="classesToBeBound">
        <list>
            <value>com.xyz.RequestPojo</value>
            <value>com.xyz.ResponsePojo</value>
        </list>
    </property>
</bean>

几个好的例子 -here http://devilspace.org/2013/07/05/how-to-make-xsd-validation-in-a-rest-based-web-service-xml-request-by-using-xsd-file-and-jaxbmarshaller/ and here http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html?ca=drs-

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring:根据 XSD 架构验证 REST 控制器 的相关文章

  • 在 MacOS 命令行上使用 Android Studio 内置 Java

    这里有很多关于在 Mac 上安装 Java 以及让 Android Studio 使用正确版本的信息 很多已经过时 但是最近版本的 Android Studio 2 2 及更高版本 提供了自己的 Java 对于大多数 Mac 用户来说 没有
  • 如何在运行时创建对象?

    我需要在运行时创建一个类的多个不同对象 这个数字也是在运行时确定的 就像我们在运行时得到 int no o objects 10 一样 然后我需要实例化一个类10次 Thanks 阅读Java 教程中的数组 http java sun co
  • Glassfish 使用内部模块库而不是应用程序库

    我正在尝试在 Glassfish 4 1 21 上部署 Spring boot 应用程序 在启动时 我收到一条错误 指出由于方法不存在而无法创建entityManagerFactory 它不存在 因为由于某种原因 当应用程序在 glassf
  • Ionic 3 项目没有 config.xml

    我试图遵循本教程 https www youtube com watch v SOOjamH1bAA https www youtube com watch v SOOjamH1bAA 但我什至无法开始 因为从看起来来看 我的项目没有 co
  • Java 8 模块与 OSGi 有何不同?

    Java 8 和 Jigsaw 项目为 SDK 带来了模块系统 我认为这是一件好事 因为它是软件包的一部分 内置 OSGi 还提供了一个模块系统 但需要一个容器 但除此之外 它们之间的主要区别是什么 如果我使用 OSGi 我是否能够使用标准
  • Freemarker、PDF、页眉/页脚和分页符

    Freemarker 的一个常见用途是生成 PDF 不幸的是 我必须生成一个包含很多页面的pdf 并且 他们 要求我添加包含一些信息的页眉和包含 第2 60页 等内容的页脚 在网上搜索我找到了如何创建宏模板 但它只共享一些常见标签 如css
  • 如何在 Spring Boot 中使用 CommonsMultipartResolver

    我尝试在 Boot 中使用 CommonsMultipartResolver 将我的旧应用程序 WAR 转换为 Boot 现在它得到以下代码 Configuration public class TestConfig Bean public
  • Java JDK中有并发List吗?

    如何创建一个并发 List 实例 在其中可以按索引访问元素 JDK 有我可以使用的类或工厂方法吗 ConcurrentLinkedQueue 如果您不关心基于索引的访问 而只想要列表的插入顺序保留特性 那么您可以考虑java util co
  • 使用jsoup从两个标签之间提取未识别的html内容?正则表达式?

    我想获取两者之间所有链接的名称h2那里有标签 h2 span class mw headline People span span class mw editsection span class mw editsection bracket
  • Jenkins 中的算法协商失败 SSH

    我正在尝试从 Jenkins ssh 到本地服务器 但抛出以下错误 SSH Exception Algorithm negotiation fail com jcraft jsch JSchException Algorithm negot
  • 解压jar到指定目录

    我想使用以下命令将我的罐子之一提取到指定目录jar命令行实用程序 如果我理解正确的话 C选项应该能解决问题 但是当我尝试时 jar xvf myJar jar C directoryToExtractTo 我从 jar 实用程序获取使用信息
  • 如何在 IE 受信任的根证书颁发机构存储中自动安装自签名证书

    我创建了一个自签名证书 但浏览器告诉我 此 CA 根证书不受信任 要启用信任 请在受信任的根证书颁发机构存储中安装此证书 我通过进入 IE gt Internet 选项 gt 内容 gt 证书 gt 等 我实际上必须导出自签名证书 然后将其
  • 终极Java版本表(J2EE、Java EE、Servlet、JSP、JSTL)

    我正在寻找 Java EE 或以前称为 J2EE 和 Java SE 的组件分解 E g J2EE 1 3 Servlet 2 3 JSP 1 2 JSTL 1 0 J2EE 1 4 Servlet 2 4 JSP 2 0 JSTL 1 1
  • Java 类卡枚举示例。修改

    任何帮助深表感谢 我正在使用 java 网站上的类卡示例来尝试构建游戏 http java sun com j2se 1 5 0 docs guide language enums html http java sun com j2se 1
  • 使用 Lucene 提取英语单词词干

    我正在 Java 应用程序中处理一些英文文本 我需要对它们进行词干处理 例如 从文本 amenities amenity 中我需要获取 amenit 该函数如下所示 String stemTerm String term 我找到了 Luce
  • 国际象棋棋步验证库[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 NET 中是否有可用于验证国际象棋走法和模拟游戏的库 如果该库能够理解代数符号中的移动并提供简单的 A
  • 使用 Apache CXF 2.4 JAX-RS 和 Spring Security 3.2 获取用户名

    我在 JAX RS 资源中获取用户名SecurityContextHolder这有效 Path myresource public class MyResoure Get public String getUserName return S
  • StringBuilder 与 Java 中 toString() 中的字符串连接

    鉴于 2toString 下面的实现 哪一个是首选 public String toString return a a b b c c or public String toString StringBuilder sb new Strin
  • 构建失败:程序类型已存在:com.facebook.ads.Ad

    我尝试在 Android Studio 中构建一个模块 它似乎可以在设备上运行 但是当我尝试构建 APK 时 出现错误 Program type already present com facebook ads Ad 这是完整的日志 org
  • java中的长轮询

    我已经编写了用于长轮询的服务器端代码 我想用java写客户端程序 因此 根据长轮询 客户端发送一个由服务器帮助的请求 当事件发生时服务器响应该请求 然后客户端发送新的请求 所以我面临的麻烦是用java编写的客户端 发送请求后 如何继续检查客

随机推荐

  • 嵌套函数内间隔上的多个 CASE 语句

    虽然我已经想出了一个使用多个的解决方法if else if声明 我很想知道我的case声明 如下图所示 function ar vo bucket revEng v s solve solve gt 0 sqrt T ar vo s buc
  • 为什么Java String 实现中存在偏移量?

    我一直在研究实现 但不明白为什么会有偏移 我认为这很重要 我正在学习 Sedgewick 教授的算法课程 我们现在正在讨论字符串 在讲座中 他简要讨论了 String 的实现 但他没有详细说明为什么会有偏移 注意 如果讲座不是在线的 我肯定
  • RFC2898DeriveBytes 如何生成 AES 密钥?

    我看到一些代码像 string password 11111111 byte salt Encoding ASCII GetBytes 22222222 Rfc2898DeriveBytes key new Rfc2898DeriveByt
  • 不带参数的 getter 的 WSDL 类型

    我尝试编写一个 wsdl 文件 我首先在元素中定义我未来的运营 所以我需要定义一个像 getAllObjects 这样的方法 这就是为什么我不需要为 getAllObjectsRequest 设置任何参数 谁能告诉我如何为未声明任何输入参数
  • UIApplication.delegate 必须仅在主线程中使用[重复]

    这个问题在这里已经有答案了 我的应用程序委托中有以下代码 作为在其他 viewController 中使用 CoreData 的快捷方式 let ad UIApplication shared delegate as AppDelegate
  • 保存模式后立即替换数字

    搜索到的模式看起来像text9 我寻找 text 9 我想替换为 15这样我就能得到text5但它只是给了我text 除数字外 任何其他字符都有效 事实证明 PCRE 风格的反向引用不起作用 所以 你必须使用 015替换为第一个捕获组捕获的
  • AOP Spring @AfterReturning 未按预期工作

    我正在学习 AOP spring 并尝试一些例子 关于 AfterReturning 我所理解的是 仅当目标成功返回并且与切入点匹配时才会调用该方法 然而 在我的例子中 如下所示 我有一个切入点 它定义了仅返回字符串的所有方法 但它调用了所
  • 如何将 JavaPairRDD 转换为数据集?

    SparkSession createDataset 只允许List RDD or Seq 但不支持JavaPairRDD 所以如果我有一个JavaPairRDD
  • Tomcat 中连接的唯一标识符

    我想为与 Tomcat 建立的每个连接获取唯一标识符 我不是在谈论会话或用户 客户端 的唯一性 而是在谈论每个连接 假设客户端 A 发送一个 GET 然后发送另一个 在我的场景中 这是两个独立且独特的连接 Tomcat 中是否有任何变量或东
  • Python3导入相对或绝对的正确方法?

    我正在写一个 python 模块神经网络 它在 Python2 中运行良好 但在 Python3 中导入失败 这是我的代码结构 neuralnet init py train py A wrapper to train does not d
  • 如何让 Squeryl 与 Play 一起使用!框架?

    我正在尝试学习如何使用 Play 和 Squeryl 制作一个简单的数据库应用程序 我已经根据 Play 教程制作了任务应用程序 但我想更改模型 架构 以便它使用 Squeryl 而不是 Anorm 我一直在寻找不同的教程 http squ
  • 在泽西岛为自己的服务编写代理/包装类

    我想访问运行基本 http 身份验证的完整休息服务 然而 当 a提供了错误的凭证 https stackoverflow com questions 86105 how can i supress the browsers authenti
  • Spring boot 1.5.9,访问 Docker 容器内的资源镜像时出现 404 错误

    在 Spring Boot 1 5 9 应用程序中 我想使用 Google Chrome 通过 HTTP 访问静态资源 在 Docker 中我有404 error 在嵌入式tomcat中运行良好 配置 这是Dockerfile FROM o
  • 将blob发送到pythonflask然后保存

    所以我正在尝试制作一个记录你的声音的网站 问题是当我将 blob 文件或 blob url 发送到 Flask 服务器时 我的 Flask python 代码说没有内容 而它是 我该如何发送blob 因此服务器可以将其保存为文件 media
  • 如何在 XCode 6 iOS 模拟器中运行/录制 iOS 应用程序?

    我可能会犯这个错误 但我正在尝试在 Xcode 6 iOS 模拟器中运行 iOS 应用程序 以便录制该应用程序的视频教程 我已经安装了 xCode 并且可以启动 iOS 模拟器 但似乎无法安装 app 文件 Library Develope
  • Maven增量构建

    我们目前有一个大型 Maven 2 项目 它是许多具有复杂依赖关系的单个独立项目的集合 除了一些用于构建的通用父 POM 之外 最后 我们总是必须将应用程序作为一个整体进行交付 因此我宁愿将其转换为一个或几个大项目 有谁有如何优化大型项目的
  • 我应该为 Spark 选择哪种集群类型? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我是 Apache Spark 的新手 刚刚了解到 Spark 支持三种类型的集群 独立 意味着 Spark 将管理自己的集群 YARN 使用
  • 具有 has_many 和 has_one 多态关联的工厂女孩

    我目前正在开发一个项目 我想使用 Factory Girl 创建测试 但我无法使其与多态 has many 关联一起工作 我已经尝试了其他文章中提到的许多不同的可能性 但它仍然不起作用 我的模型看起来像这样 class Restaurant
  • C# 合并两个集合的不同项

    我正在寻找一种高性能的方法来将第二个 ICollection 的不同项目添加到现有的 ICollection 中 我正在使用 NET 4 这应该可以做到 list1 Union list2 Distinct aCustomComparer
  • Spring:根据 XSD 架构验证 REST 控制器

    目前我有 RestController 和以下代码 package be smartask api import be smartask api model NumberValue import be smartask api model