【问题标题】:spring boot jpa app, crudRepo Error (type=Bad Request, status=400). Validation failed for objectspring boot jpa app,crudRepo 错误(类型=错误请求,状态=400)。对象验证失败
【发布时间】:2022-01-26 21:13:30
【问题描述】:

我正在开发一个简单的 Spring-Boot CRUD 应用程序,我正在尝试使用 CrudRepository 更新或创建新实体实例并保存它们,但我不断收到 (type=Bad Request, status=400 ) 错误,但我真的没有任何验证,我不知道可能是错误,我正在使用旧版本的 spring-boot 来实现旧的 Java 兼容性,因为我将部署应用程序的服务器。 这是我的实体

@Entity
@Table(name = "AAA_TEST_DM_DATA")
public class DataDM implements Serializable{

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_TIENDA")
    private Tienda tienda;

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

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

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "DATA_ID")
    private Long id;

这是我扩展 CrudRepository 的 Dao 或 repo

public interface IDataDMDao extends CrudRepository <DataDM, Long> {

    DataDM findByTienda(Tienda tienda);
    
}

这是我的服务

public interface IDataDMService {

    public List<DataDM> findAll();

    public DataDM findOne(Long id);

    public void save(DataDM dataDM);

    public boolean exists(Tienda tienda);

    public DataDM findDm(Tienda tienda);

    
}

这里是服务实现

@Service
public class IDataDMServiceImp implements IDataDMService {

    @Autowired
    private IDataDMDao dataDMDao;


    @Override
    @Transactional(readOnly = true)
    public List<DataDM> findAll(){
        return (List<DataDM>) dataDMDao.findAll();
    }

    @Override
    @Transactional(readOnly = true)
    public DataDM findOne(Long id){
        return dataDMDao.findOne(id);
    }

    @Override
    @Transactional
    public void save(DataDM data){
        dataDMDao.save(data);
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean exists(Tienda tienda){
        
        if (dataDMDao.findByTienda(tienda) == null){
            return false;
        } else {
            return true;
        }
    }

    @Override
    @Transactional(readOnly = true)
    public DataDM findDm(Tienda tienda){
        return dataDMDao.findByTienda(tienda);
    }
}

这里是控制器

@SessionAttributes("data")
public class DesController {

    @Autowired
    private ITiendaService tiendaService;

    @Autowired
    private IDataDMService dataService;

    @Autowired
    private ISesionTiendaService sesionService;


    //LOOK AT ALL DATADM
    @RequestMapping("/data")
    public String dataList(Model model){
        model.addAttribute("title", "Datos de tiendas");
        model.addAttribute("dataList", dataService.findAll());
        return "datas";

    }


    @RequestMapping("/captura")
    public String form(Model model, 
    @RequestParam(value = "_paramsP_ID") String idsesion,
    HttpServletRequest request){

        Integer idses = Integer.parseInt(request.getParameter("_paramsP_ID"));

        //get tiendaid based on idses
        SesionTienda sesion = sesionService.findSesion(idses, "FLT_TIENDA");
        Integer id = Integer.parseInt(sesion.getValor());

        //get tienda based on given id, then checks if there is data for that tienda
        Tienda tienda = tiendaService.findOne(id);
        boolean check = dataService.exists(tienda); 
        DataDM data = null;

         //if there is no data create new data entity for that tienda
         if (check == false){

            data = new DataDM();
            data.setTienda(tienda);
            //dataService.save(data);
            model.addAttribute("data", data);
            model.addAttribute("title", "Tiendas form");
            return "form";

        }

        //if there is data, find it and pass it into the model
        data = dataService.findDm(tienda);
        model.addAttribute("data", data);
        model.addAttribute("title", "Tiendas form");
        return "form";        
    }

    //Saves the DataDM entity from the form
    @RequestMapping(value = "/form", method = RequestMethod.POST)
    public String save(Model model, DataDM data, SessionStatus status)
    {
        dataService.save(data);
        status.setComplete();
        return "redirect:/success";
    } 

从给定的参数我得到 Tienda id,我想用这个 Id 查看是否是该 Tienda 的 DataDM 实例,如果存在则使用表单更新它,如果没有实例则创建并保存它,一切正常(findByTienda 工作),直到我从它给我错误的表单中单击保存按钮: (类型=错误请求,状态=400)。 对象 ='dataDM' 的验证失败。错误计数:1,但我真的没有任何验证来保存 DataDM 实体,我想它必须与 save() 方法有关,但我不知道可能是什么,有人可以帮助我吗?

编辑:添加客户端代码

    <!DOCTYPE html>
<html lang="en" xmlns:th="/http:wwww.thymeleaf.org">
<head th:replace="layout/layout :: head"></head>
<body>
<header th:replace="layout/layout :: header"></header>
    
    <div class="container">

        <h3 th:text=" 'CAPTURA PARA TIENDA ' + ${data.tienda.id} + ' ' + ${data.tienda.nombreTienda} "></h3>

        <div class="container">

            <form th:action="@{/form}" th:object="${data}" method="post" class="d-flex align-content-start flex-wrap p-2">

                <label for="sec-1" class="h4" th:text=" 'ALREDEDORES DE TIENDA' "></label>
                <div class="d-flex align-content-start flex-wrap" id="sec-1" name="sec-1" >
                    <div class="form-group p-2">
                        <select th:field="*{nse}" id='nse' name="nse" class="form-control">
                            <option th:value=" '-' "  th:text=" '-' "></option>
                            <option th:value=" 'AB' " th:text=" 'AB' "></option>
                            <option th:value=" 'C+' " th:text=" 'C+' "></option>
                            <option th:value=" 'C' "  th:text="  'C' "></option>
                            <option th:value=" 'C-' " th:text=" 'C-' "></option>
                            <option th:value=" 'D' "  th:text="  'D' "></option>
                        </select>
                    </div>
                <div class="form-group p-2">
                <input type="submit" value="Guardar Datos" class="btn btn-secondary btn-block" />
                </div>

                <input type="hidden" th:field="*{id}"/>
                <input type="hidden" th:field="*{tienda}"/>
                </form>
</div>

【问题讨论】:

    标签: java spring spring-boot spring-data-jpa crud-repository


    【解决方案1】:

    Bad Request 表示服务器无法处理请求(因此您的服务器代码无法运行),通常表示存在客户端错误,因此您应该检查您的客户端代码...

    编辑: save 方法默认需要 JSON,因此您可以发送 JSON,但它涉及添加 JavaScript,或者您可以告诉您的 API 方法使用不同类型的数据,如下所示:

    @PostMapping(
      path = "/save",
      consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
    

    【讨论】:

    • 但是我不明白为什么,与数据库的通信正在工作,例如,如果我这样做data = new DataDM(); data.setTienda(tienda);dataService.save(data); model.addAttribute("data", data); 它工作正常,它会保存新实例,我不知道为什么当我通过表单的 save(requestMethod.Post) 控制器方法传递实例时不保存实例。
    • 听起来我是对的,你没有到达控制器,因为你的客户端请求格式不正确,这就是你得到 400 的原因。
    • 可以帮忙解决吗?你能看出我在哪里做的不好吗?
    • 您必须从客户端粘贴代码...
    • 我添加了它(我认为)用户唯一使用的是表单,我添加了使用百里香的表单的 html 代码,这是你的意思吗?
    猜你喜欢
    • 2013-07-21
    • 2020-10-21
    • 2018-02-23
    • 2021-05-30
    • 1970-01-01
    • 2021-09-24
    • 2017-12-20
    • 2016-04-20
    • 2021-09-19
    相关资源
    最近更新 更多