无法将“java.lang.String”类型的值转换为嵌套的所需类型“java.lang.Long”,除了 java.lang.NumberFormatException 对于输入字符串“null”

问题描述 投票:0回答:2

我遇到了这个错误,不知道还需要解决什么问题。我只是想让用户单击“rsvp”按钮,并将其与点击该按钮的用户 ID 一起注册到数据库。每次我单击该按钮时,它都会将我带到 url /event/null 。任何帮助将不胜感激!

Event.java:

@Entity
public class Event {

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

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "user_id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private User user;
    
    private String message;
    
    @JoinTable(name = "rsvp_status", joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "event_id"))
    private Boolean rsvp = false;
    
    
    @CreationTimestamp
    private Date createdAt;

    
    
    public Event() {}
    
    
    
    
    public Event(User user, String message, Boolean rsvp, Date createdAt) {
        this.user = user;
        this.message = message;
        this.rsvp = rsvp;
        this.createdAt = createdAt;
    }




    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }


    public Boolean getRsvp() {
        return rsvp;
    }


    public void setRsvp(Boolean rsvp) {
        this.rsvp = rsvp;
    }




    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    @Override
    public String toString() {
        return "Event [id=" + id + ", user=" + user + ", message=" + message + ", rsvp=" + rsvp + ", createdAt="
                + createdAt + "]";
    }
}

活动服务:

@Service
public class EventService {
    
    @Autowired
    private EventRepository eventRepository;
    
    @Autowired 
    UserService userService;

    
    public Event findEventById(Long id) {
        Optional<Event> optionalEvent = eventRepository.findById(id);
        
        Event event = null;
        
        if(optionalEvent.isPresent()) {
            event = optionalEvent.get();
            return event;
        } else {
            return event;
        }
    }
    
    public List<EventDisplay> findAll() {
        List<Event> events = eventRepository.findAllByOrderByCreatedAtDesc();
        return formatEvents(events);
    }
        
    public List<EventDisplay> findAllByUser(User user) {
        List<Event> events = eventRepository.findAllByUserOrderByCreatedAtDesc(user);
        return formatEvents(events);
    }
        
    public List<EventDisplay> findAllByUsers(List<User> users){
        List<Event> events = eventRepository.findAllByUserInOrderByCreatedAtDesc(users);
        return formatEvents(events);
    }
    
    public void save (Event event) {
        eventRepository.save(event);
    }


    private List<EventDisplay> formatEvents(List<Event> events) {
        List<EventDisplay> displayEvents = formatTimestamps(events);
        return displayEvents;
    }

    private List<EventDisplay> formatTimestamps(List<Event> events) {
        List<EventDisplay> response = new ArrayList<>();
        PrettyTime prettyTime = new PrettyTime();
        SimpleDateFormat simpleDate = new SimpleDateFormat("M/d/yy");
        Date now = new Date();
        for (Event event : events) {
            EventDisplay eventDisplay = new EventDisplay();
            eventDisplay.setUser(event.getUser());
            eventDisplay.setMessage(event.getMessage());
            long diffInMillies = Math.abs(now.getTime() - event.getCreatedAt().getTime());
            long diff = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
            if (diff > 3) {
                eventDisplay.setDate(simpleDate.format(event.getCreatedAt()));
            } else {
                eventDisplay.setDate(prettyTime.format(event.getCreatedAt()));
            }
            response.add(eventDisplay);
        }
        return response;
    } 

回复控制器:

@Controller
public class RsvpController {
    @Autowired
    private UserService userService;
    
    @Autowired
    EventService eventService;
    
    @PostMapping(value = "/event/{id}")
    public String rsvp(@PathVariable Long id, @RequestParam String submit, Event event, HttpServletRequest request,
            Model model) {
        //getting the event by Id
        Event eventToRsvp = eventService.findEventById(id);
        if(submit.equals("up")) {
            if(eventToRsvp != null) {
                event.setRsvp(true);
                eventService.save(event);
            } 
            
        }
        return "redirect:" + request.getHeader("Referer");
    }
}

Events.html:

<form  th:action="@{/event/} + ${eventToRsvp}" method = "post">
                    <button style="float: right;" type="Submit" value="up"
                        class="btn btn-lg btn-primary">RSVP</button>
                </form>

我的控制台日志中的错误:

2021-03-29 18:08:21.511  WARN 17584 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "null"]
java spring-boot thymeleaf
2个回答
0
投票

看起来错误可能来自您的

rsvp()
方法。对于
@PathVariable Long id
,它需要
Long
类型,但您传入的是
String
类型。您可以执行
Long.parseLong(id)
String
转换为
Long
。看起来您也将
String
"null"
表示传递到这个
id
中?不过,让我知道修复第一个错误后您会得到什么。


0
投票

我认为错误在于

th:action
url。尝试

th:action="@{'/event/' + ${eventToRsvp}}"

或者 通过在路径变量周围放置双下划线,可以将路径变量从 thymeleaf 页面传递到控制器方法。

th:action="@{/event/__${eventToRsvp}__}"
© www.soinside.com 2019 - 2024. All rights reserved.