【问题标题】:Spring MVC: issue between xml and annotation configurationsSpring MVC:xml和注释配置之间的问题
【发布时间】:2023-03-31 19:51:01
【问题描述】:

我已经创建了一个简单的控制器

@GetMapping("/playerAccount")
    public Iterable<PlayerAccount> getPlayerAccounts(com.querydsl.core.types.Predicate predicate) {
        return repository.findAll(predicate);
    }

当我调用 GET /playerAccount API 时,我收到异常 IllegalStateException “No primary or default constructor found for interface com.querydsl.core.types.Predicate”(由 org.springframework.web.method.annotation.ModelAttributeMethodProcessor 抛出#createAttribute)。

经过一些(深入!)挖掘后,我发现如果我删除 spring.xml 文件中的以下行:

 <mvc:annotation-driven />

如果我在 Spring.java 文件中添加以下行:

@EnableWebMvc

然后问题就消失了。

我真的不明白为什么。这可能是什么原因?我认为这些确实是等价的(一个是基于 xml 的配置,另一个是基于 java/annotation)。

我阅读了 this documentation 关于结合 Java 和 Xml 配置的内容,但我没有看到任何相关内容。


编辑:

从我目前获得的(少数)cmets/answers 来看,我知道在我的 API 中使用谓词可能不是最佳选择。

虽然我真的很想了解错误的性质,但我首先想解决我试图解决的最初问题:

假设我有一个 MyEntity 实体,它由 10 个不同的字段(具有不同的名称和类型)组成。我想轻松搜索它。如果我创建以下(空)接口:

public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, QuerydslPredicateExecutor<MyEntity> {
}

然后无需任何其他代码(除了 xml 配置),我就可以轻松地在数据库中搜索 myEntity 实体。

现在我只想将该功能公开给 Rest 端点。理想情况下,如果我向我的 MyEntity 添加一个新字段,我希望该 API 能够自动使用该新字段,就像 MyEntityRepository 所做的那样,而无需修改控制器。

我认为这是 Spring Data 的目的和一个好方法,但请告诉我是否有更好/更常见的方法来为给定实体创建搜索 API。

【问题讨论】:

  • 你能分享整个控制器代码吗?
  • 控制器只包含这一种方法。
  • 你添加了spring web依赖吗?
  • 我的 maven pom.xml 中有一个 org.springframework:spring-web 依赖项,如果这就是你要问的。它与 java 注释一起工作,没有任何其他更改,但使用等效的 xml 配置引发异常。 pom.xml 或其他任何内容都没有更改。
  • 取决于 Spring 版本,可能存在一些细微的差异(出于历史原因)。然而,让人们创建这样的谓词是等待发生的麻烦。

标签: java spring spring-mvc spring-data-jpa spring-annotations


【解决方案1】:

我没有看到它返回异常,这就是为什么我认为这是一个依赖问题。
试着让你的代码看起来像这样,它会做到的。

@RestController
public class MyClass {

    @Autowired
    private final MyRepository repository;
    @GetMapping("/playerAccount")
    public Iterable<PlayerAccount> getPlayerAccounts() {
        return repository.findAll();
    }

如果您的请求中有参数,请添加@RequestParam。 代码时间(yaaaaaay):

@RestController
public class MyClass {

    @Autowired
    private final MyRepository repository;
    @GetMapping("/playerAccount")
    public Iterable<PlayerAccount> getPlayerAccounts(@RequestParam(required = false) Long id) {
        return repository.findById(id);
    }

Ps:请求应该保持相同的变量名,例如

.../playerAccount?id=6

【讨论】:

  • 好吧,在这种情况下,用户无法像以前那样在 playerAccount 上进行搜索。例如,localhost/playerAccount?name=foo
  • 你只需要添加RequestParam注解,我会修改代码让你更清楚。
  • 那么 PlayerAccount 中的所有其他字段怎么样?最后,我希望能够以最少的编码从 REST API 搜索我的对象的所有字段。这就是为什么我认为使用查询 dsl 很方便。但是,如果有另一种更清洁的方法,请指点我一个解释如何做到这一点的教程。
  • 对于多个参数同名,可以使用 Map 。我没有要分享的链接,但我会寻找可以帮助你的东西。
  • 假设我有一个 MyEntity 实体,它由 10 个不同的字段(具有不同的名称和类型)组成。我想轻松搜索它。如果我创建一个扩展 QuerydslPredicateExecutor(和 JpaRepository)的 MyEntityRepository 接口,而无需任何其他代码,我就可以轻松地在数据库中搜索一个 myEntity 实体。现在我只想将该功能公开给 Rest 端点。理想情况下,如果我向 MyEntity 添加一个新字段,我希望该 API 能够自动使用该新字段,就像存储库一样。使用您的方法,我将不得不修改控制器。
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
  • 2015-12-19
  • 2013-02-09
相关资源
最近更新 更多