【问题标题】:Deserialize from Number value to int (error - no int/Int-argument constructor/factory method to deserialize from Number value) while posting data发布数据时从 Number 值反序列化为 int(错误 - 没有 int/Int-argument 构造函数/工厂方法从 Number 值反序列化)
【发布时间】:2021-12-21 06:56:34
【问题描述】:

我之前问过基本相同的问题并以某种方式解决了,但这里又出现了一个问题:

我正在从我的 Angular 12 应用发送帖子数据

{
  "qty": 2,
  "paid": 200,
  "ticketid": 2
}

这是用于在 java 中看起来像这样的 userticket 模型:

package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "tickettouser")

public class TicketUser {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
     @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "userid", nullable = false)
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Users userid;

     @Column(name = "qty")
     private int qty;

     @Column(name = "paid")
     private float paid;

     @JsonIgnoreProperties({"hibernateLazyInitializer", "handler","ignoreUnknown = true"})
        
        @ManyToOne(fetch = FetchType.LAZY, optional = false)
            @JoinColumn(name = "ticketid", nullable = false)
            @OnDelete(action = OnDeleteAction.CASCADE)
            private Tickets ticketid;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Users getUserid() {
        return userid;
    }

    public void setUserid(Users userid) {
        this.userid = userid;
    }

    public int getQty() {
        return qty;
    }

    public void setQty(int qty) {
        this.qty = qty;
    }

    public float getPaid() {
        return paid;
    }

    public void setPaid(float paid) {
        this.paid = paid;
    }

    public Tickets getTicketid() {
        return ticketid;
    }

    public void setTicketid(Tickets ticketid) {
        this.ticketid = ticketid;
    }

     
}

完整的错误:

2021-11-08 14:07:46.938  WARN 8180 --- [nio-8888-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.example.model.Tickets` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (2); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.example.model.Tickets` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (2)
 at [Source: (PushbackInputStream); line: 1, column: 32] (through reference chain: com.example.model.TicketUser["ticketid"])]

还有我的票模型

package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "tickets")

public class Tickets {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    
     
     @Column(name = "price")
     private Float price;
    
     @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

        @ManyToOne(fetch = FetchType.LAZY, optional = false)
            @JoinColumn(name = "event_id", nullable = false)
            @OnDelete(action = OnDeleteAction.CASCADE)
            private Events eventid;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    
    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public Events getEventid() {
        return eventid;
    }

    public void setEventid(Events eventid) {
        this.eventid = eventid;
    }

}

最后是我的ticketuser控制器

package com.example.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.example.model.TicketUser;
import com.example.security.services.UserDetailsImp;
import com.example.model.Cities;
import com.example.model.Events;
import com.example.model.Halls;
import com.example.service.UsersticketService;
import com.example.service.EventsService;
import com.example.service.HallsService;
import com.example.service.UsersService;
import com.example.model.Users;
@Controller
@RequestMapping(value="/userticket")
@SpringBootApplication
@CrossOrigin(origins = "http://localhost:8889")

public class UsersTicketController {
    @Autowired
    UsersticketService usersticketService;
    @Autowired
    UsersService usersservice;
    @RequestMapping(value="/list", method=RequestMethod.GET)
     public ResponseEntity list()
     {
         Authentication auth = SecurityContextHolder.getContext().getAuthentication();
         String usr= auth.getName();
        
         Users user=usersservice.getUserByLogin(usr);
        int id=user.getId();
        List<TicketUser> ticketList=usersticketService.getTicketByUser(id);
        // user.getId();
         //System.out.println(user);
         
         return new ResponseEntity<>(ticketList, HttpStatus.OK);
       
     }
    
     @RequestMapping(value="/add", method=RequestMethod.POST)
        public ResponseEntity add(@RequestBody TicketUser ticket)
        {
        
         Authentication auth = SecurityContextHolder.getContext().getAuthentication();
         String usr= auth.getName();
        
         Users user=usersservice.getUserByLogin(usr);
        Users userid=new Users();
        userid.setId(user.getId());
         ticket.setUserid(userid);
         
         usersticketService.addTicket(ticket);
          return new ResponseEntity<>(ticket, HttpStatus.CREATED);

        }
     @RequestMapping(value="/delete/{id}", method=RequestMethod.GET)
        public ResponseEntity delete(@PathVariable("id") int id)
    {
     usersticketService.deleteTicket(id);

return new ResponseEntity<>(HttpStatus.NO_CONTENT);

    }
}

如您所见,我不使用任何自定义反序列化方法或类似的方法。如何解决这个问题? 如果我尝试在控制器中使用 add 方法,我会看到此错误

将添加 TicketuserRepository:

package com.example.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

//import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Pageable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;

import com.example.model.TicketUser;
import com.example.model.Users;
import com.example.model.Events;
import com.example.model.Halls;

@Repository

public interface TicketsUserRepository extends CrudRepository<TicketUser, Integer> {
    Page<Events> findByuserid(Integer userid, Pageable pageable);
    Optional<Events> findByuseridAndId(Integer userid, Integer id);


    Page<Events> findByticketid(Integer ticketid, Pageable pageable);
    Optional<Events> findByticketidAndId(Integer ticketid, Integer id);

    List<TicketUser> findByUserid(int id);

}

和服务

package com.example.service;
import java.util.List;

import com.example.model.TicketUser;
import com.example.model.Events;
import com.example.model.Halls;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.example.repository.TicketsUserRepository;
import com.example.repository.EventsRepository;
import com.example.repository.HallsRepository;
@Service
@Transactional

public class UsersticketServiceImplementation implements UsersticketService {

    @Autowired
    TicketsUserRepository ticketsuserRepository;
    
    @Override
    public List<TicketUser> getAllTickets() {
        // TODO Auto-generated method stub
        return (List<TicketUser>) ticketsuserRepository.findAll();
    }

    @Override
    public TicketUser getTicketById(int id) {
        // TODO Auto-generated method stub
        return ticketsuserRepository.findById(id).get();
    }

    @Override
    public void addTicket(TicketUser ticketuser) {
        // TODO Auto-generated method stub
        ticketsuserRepository.save(ticketuser);
        
    }

    @Override
    public void deleteTicket(int id) {
        // TODO Auto-generated method stub
        ticketsuserRepository.deleteById(id);
        
    }

    @Override
    public List<TicketUser> getTicketByUser(int id) {
        // TODO Auto-generated method stub
        return (List<TicketUser>) ticketsuserRepository.findByUserid(id);
    }
    

}

这是我的 Angular 模型用户票:

import {Ticket} from "./ticket.model";

export class Userticket {
  id?:any;
  qty?:number;
  paid?:number;

  ticketid?:Ticket;

}

将从角度添加我的ticketuser组件

import { Component, OnInit } from '@angular/core';
import { EventService } from 'src/app/services/event.service';
import { Event } from 'src/app/models/event.model';
import {TicketService} from 'src/app/services/ticket.service';
import {Ticket} from "../../models/ticket.model";
import {Userticket} from "../../models/userticket.model";
import {UserticketService} from "../../services/userticket.service";
import {ActivatedRoute, Router} from "@angular/router";

@Component({
  selector: 'app-userticket-buy',
  templateUrl: './userticket-buy.component.html',
  styleUrls: ['./userticket-buy.component.css']
})
export class UserticketBuyComponent implements OnInit {
  currentTicket: Ticket = {
    price: 0,
    eventid:this.retrieveEvents()



  };
  eventid = this.currentTicket.eventid;

  events?: Event[];
  submitted = false;

  currentUserTicket: Userticket = {
    qty: 1,
    paid:0,



  };
  //final current

  //end
  message = ''

  constructor(
    private eventService: EventService,
    private ticketService:TicketService,
    private userticketService:UserticketService,
    private route: ActivatedRoute,
    private router: Router) { }

  ngOnInit(): void {
    this.message = '';
    this.getTicket(this.route.snapshot.params.id);

  }
  getTicket(id: string): void {
    this.ticketService.get(id)
      .subscribe(
        data => {
          this.currentTicket = data;
          console.log(data);
        },
        error => {
          console.log(error);
        });
  }
  //save order
  saveOrder(): void {
    const data = {
      qty: this.currentUserTicket.qty,
      paid: this.currentUserTicket.paid,

      ticketid: this.currentTicket.id

    };
    //console.log(data.eventid);
    this.userticketService.create(data)
      .subscribe(
        response => {
          console.log("city")
          console.log(response);
          this.submitted = true;
        },
        error => {
          console.log(error);
        });
  }
  //end

  retrieveEvents(): any {
    this.eventService.getAll()
      .subscribe(
        data => {
          this.events = data;
          console.log(data);
          return data;
        },
        error => {
          console.log(error);
          return error;
        });

  }
  calculatePrice($event:any){
  let n1:number|undefined;
  n1=this.currentTicket.price;
    let n2:number|undefined;
    n2=this.currentUserTicket.qty  || 1;
    let res:number|undefined;
   res=n1  || 1 * n2  || 1;
  console.log(this.currentUserTicket.qty);
    // @ts-ignore: Object is possibly 'null'.
    this.currentUserTicket.paid= this.currentUserTicket.qty*this.currentTicket.price

  }
}

还有模板:

<div>
  <div *ngIf="currentTicket.id" class="edit-form">
    <h4>Билет</h4>
    <form>
      <div class="form-group">
        <label for="title">Количество</label>
        <input type="number"
               class="form-control"
               id="title"
               [(ngModel)]="currentUserTicket.qty"
               name="qty"
               (keyup)="calculatePrice($event)"
        />


        <input
          type="hidden"
          class="form-control"
          id="id"
          [(ngModel)]="currentTicket"
          name="ticketid"
        />
      </div>

      <div class="form-group">
        <label for="title">Итого</label>
        <input
          type="number"
          class="form-control"
          id="paid"
          [(ngModel)]="currentUserTicket.paid"
          name="paid"
        />


      </div>

      <div class="form-group">

        <p>Событие: {{currentTicket.eventid?.name}}</p>
        <p>Зал: {{currentTicket.eventid?.hallid?.name}}</p>
        <p>Город: {{currentTicket.eventid?.cityid?.name}}</p>





      </div>

    </form>



    <button
      type="submit"
      class="badge badge-success mb-2"
      (click)="saveOrder()"
    >
      Подтвердить
    </button>
    <p>{{ message }}</p>
  </div>

  <div *ngIf="!currentTicket.id">
    <br />
    <p>Нет доступа...</p>
  </div>
</div>

将从票证模型中添加我的工作示例: 门票.java

package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "tickets")

public class Tickets {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    
     
     @Column(name = "price")
     private Float price;
    
     @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

        @ManyToOne(fetch = FetchType.LAZY, optional = false)
            @JoinColumn(name = "event_id", nullable = false)
            @OnDelete(action = OnDeleteAction.CASCADE)
            private Events eventid;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    
    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public Events getEventid() {
        return eventid;
    }

    public void setEventid(Events eventid) {
        this.eventid = eventid;
    }

}

TicketsRepository:

package com.example.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

//import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Pageable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;

import com.example.model.Tickets;
import com.example.model.Events;
import com.example.model.Halls;

@Repository

public interface TicketsRepository  extends CrudRepository<Tickets, Integer>{
    
    
    Page<Events> findByeventid(Integer eventid, Pageable pageable);
    Optional<Events> findByeventidAndId(Integer eventid, Integer id);

}

票务服务:

package com.example.service;
import java.util.List;

import com.example.model.Tickets;
import com.example.model.Events;
import com.example.model.Halls;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.repository.EventsRepository;
import com.example.repository.HallsRepository;
import com.example.repository.TicketsRepository;
@Service
@Transactional

public class TicketsServiceImplementation implements TicketsService {

    @Autowired
    TicketsRepository ticketsRepository;

    @Override
    public List<Tickets> getAllTickets() {
        // TODO Auto-generated method stub
        return (List<Tickets>) ticketsRepository.findAll();
    }

    @Override
    public Tickets getTicketById(int id) {
        // TODO Auto-generated method stub
        return ticketsRepository.findById(id).get();
    }

    @Override
    public void addTicket(Tickets ticket) {
        // TODO Auto-generated method stub
        ticketsRepository.save(ticket);
        
    }

    @Override
    public void deleteTicket(int id) {
        // TODO Auto-generated method stub
        ticketsRepository.deleteById(id);
        
    }

}

还有控制器:

package com.example.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.example.model.Tickets;
import com.example.model.Events;
import com.example.model.Halls;
import com.example.service.TicketsService;
import com.example.service.EventsService;
import com.example.service.HallsService;

@Controller
@CrossOrigin(origins = "http://localhost:8889")

@RequestMapping(value="/ticket")
@SpringBootApplication

public class TicketsController {
    @Autowired
    TicketsService ticketsService;
    @RequestMapping(value="/list", method=RequestMethod.GET)
     public ResponseEntity list()
     {
         List<Tickets> ticketList=ticketsService.getAllTickets();
         
         return new ResponseEntity<>(ticketList, HttpStatus.OK);
       
     }
    
    @RequestMapping(value="/add", method=RequestMethod.POST)
    public ResponseEntity add(@RequestBody Tickets ticket)
    {
     ticketsService.addTicket(ticket);
      return new ResponseEntity<>(ticket, HttpStatus.CREATED);

    }

     @RequestMapping(value="/delete/{id}", method=RequestMethod.GET)
        public ResponseEntity delete(@PathVariable("id") int id)
    {
     ticketsService.deleteTicket(id);

return new ResponseEntity<>(HttpStatus.NO_CONTENT);

    }

     @RequestMapping(value="/getone/{id}", method=RequestMethod.GET)
        public ResponseEntity getOne(@PathVariable("id") int id)
    {
    Tickets ticket= ticketsService.getTicketById(id);

     return new ResponseEntity<>(ticket, HttpStatus.OK);
       
    }
}

基本上这是票据表控制器。它的制作方式基本上与 UserTicket 相同。那为什么我会遇到这个问题?

【问题讨论】:

  • 请添加服务类的更多详细信息,您如何保存ticketUser实体
  • 知道了。添加服务和存储库以防万一。
  • 这里的代码太多了。请创建一个MCVE
  • 目前没有错误。
  • @MCVE 我很乐意举一个小例子,但不知道哪种方法会产生这个错误。

标签: java json spring spring-boot


【解决方案1】:

错误是在模型中您使用的是完整的票证对象,并且也标记为nullable = false,因此在将模型保存在数据库中时,您需要使用ticketId 中的属性创建票证对象请求 json 或将模型的属性从类型 Tickets 更改为 int 您已经通过设置用户对象为用户做同样的事情。

【讨论】:

  • 有没有关于如何创建请求 Json 的示例?
  • 或者,如果我将它更改为 int,我该如何保存门票表和 ticketUser 表之间的关系?
  • 您的票证模型与事件有进一步的关系,也需要全部填充以保存关系。此外,这取决于您要如何保存的用例,您可以单独保存票证,然后将其与用户关联。在您发送 requestId 的请求中,这意味着该票是数据库中的现有票吗?如果是这样,你可以先从数据库中读取它,然后在保存之前将其与 TicketUser 模型相关联
  • 太好了。这正是我正在做的。我可以提供我的 angular 12 组件作为示例。我的意思是从数据库中获取它然后保存。此外,它在其他模型(如事件、城市等)上也能正常工作。
  • 我添加了一个 Ticket 表实体,其工作方式基本相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-12
  • 1970-01-01
  • 2020-10-06
  • 2020-04-18
  • 1970-01-01
  • 2013-04-11
  • 2017-10-19
相关资源
最近更新 更多