【问题标题】:Spring Rest `@Controller` wiered behaviourSpring Rest `@Controller` 奇怪的行为
【发布时间】:2016-12-19 06:41:13
【问题描述】:

我正在通过@Controller 尝试使用 Spring Rest 服务。但是我遇到了一个方法调用响应有效数据而其他过滤方法调用返回不正确响应的情况。这是我的controller

@Controller 
@RequestMapping("/company")
public class CompanyDetailsController {

@Autowired
private CompanyServices companyServices;

@RequestMapping(method = RequestMethod.GET)
public @ResponseBody List<CompanyDetails> getCompanyDetails() {
    return companyServices.getCompanyDetails();
}

@RequestMapping(value = "/{companyShortCode}", method = RequestMethod.GET)
public @ResponseBody CompanyDetails getCompanyDetails(@PathVariable("companyShortCode") String companyShortCode) {
    System.out.println("companyShortCode = "+companyShortCode);
    CompanyDetails companyDetails = companyServices.getCompanyDetails(companyShortCode);
    /*CompanyDetails companyDetails = new CompanyDetails();
    companyDetails.setCompanyCode("abc");
    companyDetails.setCompanyEmail("abc@123.com");
    companyDetails.setCompanyPhone(92349234);
    companyDetails.setWebSite("abc.abc.com");
    System.out.println("companyDetails = "+companyDetails);*/
    return companyDetails;
}
}

CompanyDetails

@Entity
@Table(name = "company_details")
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class CompanyDetails implements Serializable {

private static final long serialVersionUID = 8713608417980657723L;

@Id
@Column(name="COMPANY_CODE", nullable = false, updatable = false)
private String companyCode = null;

@Column(name = "COMPANY_NAME", nullable = false, updatable = true)
private String companyName = null;

@Column(name = "COMPANY_PHONE", nullable = true, updatable = true)
private long companyPhone = 0;

@Column(name = "COMPANY_EMAIL", nullable = true, updatable = true)
private String companyEmail = null;

@Column(name = "COMPANY_WEBSITE", nullable = true, updatable = true)
private String webSite = null;

public String getCompanyCode() {
    return companyCode;
}

public void setCompanyCode(String companyCode) {
    this.companyCode = companyCode;
}

public String getCompanyName() {
    return companyName;
}

public void setCompanyName(String companyName) {
    this.companyName = companyName;
}

public long getCompanyPhone() {
    return companyPhone;
}

public void setCompanyPhone(long companyPhone) {
    this.companyPhone = companyPhone;
}

public String getCompanyEmail() {
    return companyEmail;
}

public void setCompanyEmail(String companyEmail) {
    this.companyEmail = companyEmail;
}

public String getWebSite() {
    return webSite;
}

public void setWebSite(String webSite) {
    this.webSite = webSite;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
            + ((companyCode == null) ? 0 : companyCode.hashCode());
    result = prime * result
            + ((companyName == null) ? 0 : companyName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    CompanyDetails other = (CompanyDetails) obj;
    if (companyCode == null) {
        if (other.companyCode != null)
            return false;
    } else if (!companyCode.equals(other.companyCode))
        return false;
    if (companyName == null) {
        if (other.companyName != null)
            return false;
    } else if (!companyName.equals(other.companyName))
        return false;
    return true;
}

@Override
public String toString() {
    return "CompanyDetails [companyCode=" + companyCode + ", companyName="
            + companyName + ", companyPhone=" + companyPhone
            + ", companyEmail=" + companyEmail + ", webSite=" + webSite
            + "]";
}
}

Repository

@Repository
public class DetailsDaoImpl implements DetailsDao {

private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}
@Override
@Transactional(readOnly = true)
public List<CompanyDetails> getCompanyDetails() {
    List<CompanyDetails> details = (List<CompanyDetails>) sessionFactory.getCurrentSession().createCriteria(CompanyDetails.class).list();
    return details;
}

@Override
@Transactional(readOnly = true)
public CompanyDetails getCompanyDetails(String companyShortCode) {
    System.out.println("companyShortCode = "+companyShortCode);
    CompanyDetails details = (CompanyDetails) sessionFactory.getCurrentSession().load(CompanyDetails.class, companyShortCode);
    System.out.println("details = "+details);
    return details;
}
}

Service

public class CompanyServicesImpl implements CompanyServices {

@Autowired
DetailsDao detailsDao;

@Override
public List<CompanyDetails> getCompanyDetails() {
    return detailsDao.getCompanyDetails();

}

@Override
public CompanyDetails getCompanyDetails(String companyShortCode) {
    System.out.println("companyShortCode = "+companyShortCode);
    return detailsDao.getCompanyDetails(companyShortCode);
}

}

如果我打电话给List&lt;CompanyDetails&gt; getCompanyDetails(),它会返回 -

[
  {
  "companyCode": "ABCD",
  "companyName": "Test Company",
  "companyPhone": 11226123456,
  "companyEmail": "abc@abcd.com",
  "webSite": "www.abc.com"
   },
  {
  "companyCode": "XYZA",
  "companyName": "XYZA Company",
  "companyPhone": 1122000000,
  "companyEmail": "abc@XYZA.com",
  "webSite": "www.XYZA.com"
   }
]

但是当我打电话时 - Public @ResponseBody CompanyDetails getCompanyDetails(@PathVariable("companyShortCode") String companyShortCode) {, 它返回 -

{"companyPhone": 0}

我尝试使用 dummy Object 并将其转换为 Json。尝试创建普通 bean 而不是 @Entity 并使用 BeanUtils 复制属性并响应正确的 Json。有人知道为什么会这样吗?

更新

在发送响应之前,它打印为CompanyDetails [companyCode=ABCD, companyName=Test Company, companyPhone=9823611147, companyEmail=abc@abcd.com, webSite=www.abc.com]

【问题讨论】:

  • 尝试将private long companyPhone更改为private Long companyPhone
  • @Jobin 但这也不适用于 List api 调用,或者我错过了什么。将尝试检查这两种方法
  • 它是否适用于注释代码?
  • 请提供您的服务或存储库。
  • 你能贴出 CompanyServices.getCompanyDetails(String companyShortCode) 的代码吗?我在公司类中没有看到短代码。使用注释代码,您正在显式分配属性

标签: java json spring rest spring-mvc


【解决方案1】:

在您的public CompanyDetails getCompanyDetails(String companyShortCode) 方法中,当您使用其主键companyShortCode 检索CompanyDetails 对象时,您正在使用load 方法。

load 方法返回一个代理对象,其中仅设置了主键属性,而未设置所有其他属性。只有当您为 details.getCompanyEmail() 之类的属性调用任何一种 getter 方法时,您的 session 对象才会发送查询以检索实际对象。

为了避免这种情况,您可以调用get 方法。见下面代码sn-p:

@Override
@Transactional(readOnly = true)
public CompanyDetails getCompanyDetails(String companyShortCode) {
    System.out.println("companyShortCode = "+companyShortCode);
    CompanyDetails details = (CompanyDetails) sessionFactory.getCurrentSession().get(CompanyDetails.class, companyShortCode);
    System.out.println("details = "+details);
    return details;
}
}

如果您想使用加载方法,请使用以下代码 sn-p:

@Override
@Transactional(readOnly = true)
public CompanyDetails getCompanyDetails(String companyShortCode) {
    System.out.println("companyShortCode = "+companyShortCode);
    CompanyDetails details = (CompanyDetails) sessionFactory.getCurrentSession().load(CompanyDetails.class, companyShortCode);
    details.getCompanyName(); //after this all attribute of CompanyDetails object will be set
    System.out.println("details = "+details);
    return details;
}
}

更多参考请见this

希望对你有帮助。

【讨论】:

  • @Swaraj 有用吗?或者你想继续使用 load 方法。
  • 是的,它奏效了。 load 在 dao 中转换为 get 并得到了我想要的。
  • 如果你想继续加载,只需在加载方法调用后调用details.[anygetter](),你的详细信息对象将被设置为所有属性。
  • 是的.. 我错过了 Load 的这一点,并认为 Json Message 转换器会默认调用它。
  • 没关系。但现在你知道了:)
【解决方案2】:

首先代码没有完全贴出来,而且我不清楚第二次调用的响应。问题可能出在 companyservices 中,您可能在其中创建新对象,而不是从 JPA 或其底层平台获取。另一个原因可能是 JPA 配置。

【讨论】:

  • 添加了 Missing Dao 和 Services 类
  • 问题出在加载 api 上,正如@sachinsarawgi 所说,它只会返回代理对象,使用 get 而不是加载,您的代码将起作用。
猜你喜欢
  • 1970-01-01
  • 2016-04-27
  • 2012-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
相关资源
最近更新 更多