【问题标题】:Spring mvc restful - wrong json reply formatSpring mvc restful - 错误的json回复格式
【发布时间】:2014-01-26 13:32:38
【问题描述】:

回复ajax请求有一点问题。最初,我有最简单的restful服务,基于spring boot MVC

型号:

import javax.persistence.*; 
import java.util.*;

@Entity 
@Table(name = "testmodel")
public class TestModel 
{
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)//Postgresql sequence generator 
    private long id;

    @Column(name = "name")
    private String name;

    @Column(name = "content")
    private String content;


    //Constructor
    public TestModel()
    {   
    }

    //Id getter
    public long getId()
    {
        return this.id;
    }

    //Name getter-setter
    public String getName()
    {
        return this.name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    //Content getter-setter
    public String getContent()
    {
        return this.content;
    }

    public void setContent(String content)
    {
        this.content = content;
    }
}

模型的 DAO:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.*;

public interface TetsModelDAO extends JpaRepository<Samples, Long> 
{
    @Query("SELECT s FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name")
    List<TestModel> fetchByNameEntry(@Param("entry") String entry);
}

控制器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
@RequestMapping("/")
public class TestController 
{
    @Autowired
    private TetsModelDAO testmodel;

    @RequestMapping("/name")
    public List<TestModel> getDatasetsByNameEntry(@RequestParam("entry") String entry) 
    {
        return testmodel.fetchByNameEntry("%"+entry+"%");
    }
}

客户端ajax请求:

$.ajax(
{ 
  url : "/name?entry=", //get all records
  method: "GET"
})

此示例完美运行 - 字符串化回复看起来像标准 json 结构:

{"id":"1", "name":"John", "content":"blablabla1"}
{"id":"2", "name":"Sam", "content":"blablabla2"}
{"id":"3", "name":"Ken", "content":"blablabla3"}

但是,当我尝试在 JPQL 查询中明确定义文件(例如,仅获取 idname 字段)时,我得到了错误的回复结果。

带有修改查询的DAO(其他代码没有变化):

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.*;

public interface TetsModelDAO extends JpaRepository<Samples, Long> 
{
   @Query("SELECT s.id, s.name FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name")
   List<TestModel> fetchByNameEntry(@Param("entry") String entry);
}

在这种情况下,回复如下所示:

1, John, 2, Sam, 3, Ken

如何优雅地解决这个问题(不创建“帮助类”)?

【问题讨论】:

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


    【解决方案1】:

    您可以直接从 Repository 返回 DTO:

    public interface TetsModelDAO extends JpaRepository<Samples, Long> 
    {
       @Query("SELECT new mypackage.TestDto(s.id, s.name) FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name")
       List<TestDto> fetchByNameEntry(@Param("entry") String entry);
    }
    

    其中 TestDto 仅包含必填字段:

    package mypackage;
    
    public class TestDto {
      private final long id;
      private final String name;
    
      public TestDto(long id, String name) {
        this.id = id;
        this.name = name;
      }
    
      public long getId() {
        return id;
      }
    
      public String getName() {
        return name;
      }
    }
    

    【讨论】:

    • org.hibernate.hql.internal.ast.QuerySyntaxException: 无法定位类 [TestDto] [SELECT new TestDto(s.id, s.name) FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) 这是什么?与 TestDAO 在同一个包中的类 TestDto
    • 您必须在@Query 中指定您的类的全名(包括包) - 只需将其添加到我的答案中
    【解决方案2】:

    您的查询未返回TestModel 的实例。它返回对象数组(即List&lt;Object[]&gt;),每个数组包含找到的TestModel 的ID 和名称。正确的查询是

    SELECT s FROM TestModel s WHERE LOWER(s.name) LIKE LOWER(:entry) ORDER BY s.name
    

    您最好实施自动化测试来检查您的 DAO 查询是否返回了它们应该返回的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 2020-05-07
      • 2015-11-27
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      相关资源
      最近更新 更多