今天写接口返回JSON数据时,遇到一个问题,是这样的,下面是代码示例,基于SpringData JPA
一、自己封装的ResultBean,用于接收数据,响应给前端
package tonels.common;
import lombok.Data;
@Data
public class ResultBean {
private String code;
private String msg;
private Object result;
// 这个注解是后来的解决方案,先不打开,
// public ResultBean(String code, String msg, Object result) {
// this.code = code;
// this.msg = msg;
// this.result = result;
// }
public ResultBean(String code, String msg, Object... result) {
this.code = code;
this.msg = msg;
this.result = result;
}
public ResultBean(String code, String msg) {
this.code = code;
this.msg = msg;
}
public static ResultBean ok(){
return new ResultBean("200","成功");
}
public static ResultBean ok(Object result){
return new ResultBean("200","成功",result);
}
public static ResultBean ok(Object r1,Object r2,Object r3){
return new ResultBean("200","成功",r1,r2,r3);
}
public static ResultBean error(){
return new ResultBean("000", "失败");
}
public static ResultBean error(String msg){
return new ResultBean("000", msg);
}
public static ResultBean error(String code, String msg){
return new ResultBean(code, msg);
}
}
二、这是Model定义
package tonels.model;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.persistence.*;
import java.math.BigDecimal;
@Accessors(chain = true)
@Data
@Entity
@Table(name = "customers", schema = "classicmodels", catalog = "")
public class CustomersEntity {
@Id
@Column(name = "customerNumber")
private Integer customerNumber;
@Column(name = "customerName")
private String customerName;
@Column(name = "contactLastName")
private String contactLastName;
@Column(name = "contactFirstName")
private String contactFirstName;
@Column(name = "phone")
private String phone;
@Column(name = "addressLine1")
private String addressLine1;
@Column(name = "addressLine2")
private String addressLine2;
@Column(name = "city")
private String city;
@Column(name = "state")
private String state;
@Column(name = "postalCode")
private String postalCode;
@Column(name = "country")
private String country;
@Column(name = "salesRepEmployeeNumber")
private Integer salesRepEmployeeNumber;
@Column(name = "creditLimit")
private BigDecimal creditLimit;
}
三、这是controller层
package tonels.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tonels.common.ResultBean;
import tonels.service.CustomerService;
import javax.annotation.Resource;
@RestController
@RequestMapping("/customers")
public class CustomerController {
@Resource
private CustomerService customerService;
@GetMapping("/findById")
public ResultBean getS1(Integer id){
return ResultBean.ok(customerService.findById(id));
}
}
四、这是Service层
这是基础的Service,提供所有业务的service的公共方法,所有业务需要继承这个Service接口
package tonels.service;
import org.springframework.data.domain.Page;
import java.util.List;
import java.util.Set;
// V是对象,K是主键
public interface BaseService<T,K> {
boolean doCreate(T vo);
boolean doUpdate(T vo);
boolean doRemove(Set<K> ids);
T findById(K id);
List<T> findAll();
Page<T> findPages();
List<T> findAllSplit(String column,String keyword,Integer page,Integer rows);
Integer getCount(String column,String keyword);
}
package tonels.service;
import tonels.model.CustomersEntity;
public interface CustomerService extends BaseService<CustomersEntity,Integer>{
}
五、这是实现类
package tonels.service.impl;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tonels.model.CustomersEntity;
import tonels.repository.CustomerRepo;
import tonels.service.CustomerService;
import tonels.vo.mysqlVo.*;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Transactional
public class CustomerImpl implements CustomerService {
@Resource
private CustomerRepo customerRepo;
@Override
public List<CustomersEntity> findAll() {
return customerRepo.findAll();
}
}
@Override
public List<CustomersVo31> hsql_31() {
// return customerRepo.findOrdersByCust_hsql31();
return null;
}
@Override
public List<CustomersVo32> hsql_32() {
return customerRepo.findOrdersByCust_hsql32();
}
@Override
public List<CustoAndOrder> hsql_4() {
// return customerRepo.findOrdersByCust_hsql4();
return null;
}
@Override
public boolean doCreate(CustomersEntity vo) {
return false;
}
@Override
public boolean doUpdate(CustomersEntity vo) {
return false;
}
@Override
public boolean doRemove(Set<Integer> ids) {
return false;
}
@Override
public CustomersEntity findById(Integer id) {
Optional<CustomersEntity> byId = customerRepo.findById(id);
return byId.orElse(null); // 函数式编码方式
}
@Override
public List<CustomersEntity> findAllSplit(String column, String keyword, Integer page, Integer rows) {
return null;
}
@Override
public Integer getCount(String column, String keyword) {
return null;
}
@Override
public Page<CustomersEntity> findPages() {
return null;
}
}
六、Repository层
package tonels.repository;
import java.util.List;
import java.util.Map;
public interface CustomerRepo extends BaseRepository<CustomersEntity,Integer> {
}
// 需新建包
package tonels.repository;
@NoRepositoryBean
public interface BaseRepository<T,K> extends JpaRepository<T, K>,JpaSpecificationExecutor<T>{
}
七、项目启动,访问localhost:1210/customers/findByid?id=103,下面是返回数据
{
"code": "200",
"msg": "成功",
"result": [
{
"customerNumber": 103,
"customerName": "Atelier graphique",
"contactLastName": "Schmitt",
"contactFirstName": "Carine ",
"phone": "40.32.2555",
"addressLine1": "54, rue Royale",
"addressLine2": null,
"city": "Nantes",
"state": null,
"postalCode": "44000",
"country": "France",
"salesRepEmployeeNumber": 1370,
"creditLimit": 21000
}
]
}
注意到实际返回的单个对象被 中括号[ ]包裹起来了,会造成前端取数据的不方便,原因是ResultBean封装的问题,那个可变参数构造函数问题,把注释部分解开,即可返回正确数据
{
"code": "200",
"msg": "成功",
"result": {
"customerNumber": 103,
"customerName": "Atelier graphique",
"contactLastName": "Schmitt",
"contactFirstName": "Carine ",
"phone": "40.32.2555",
"addressLine1": "54, rue Royale",
"addressLine2": null,
"city": "Nantes",
"state": null,
"postalCode": "44000",
"country": "France",
"salesRepEmployeeNumber": 1370,
"creditLimit": 21000
}
}
代码简单,但是结构和包较多,可能会出现少依赖和配置错误的问题,这里不详细介绍了