【问题标题】:How to map html form data to a Spring Boot model containing a composite key?如何将 html 表单数据映射到包含复合键的 Spring Boot 模型?
【发布时间】:2020-10-23 21:08:37
【问题描述】:

我的 html 中有弹出表单,如下所示:

<dialog id="favDialog">
    <div id="feedback"></div>
    <form id="add_watchlist_symbol_form">
        <label for="symbol">Enter Symbol:</label>
        <input type="text" class="form-control" id="symbol" placeholder="SYMB"/><br><br>
        <button type="submit" class="btn btn-default" id="add-watchlist-symbol-btn">Add</button>
    </form>
    <button id="cancelBtn" value="cancel">Cancel</button>
</dialog>

点击按钮成功弹出对话框。

对话框包含一个名为“添加”的按钮。它的点击事件由 javascript 处理,它向 Spring Boot 发送一个包含表单字段值的 ajax POST 请求,如下所示:

function submit_watchlist_symbol() {
    console.log("Im in submit_watchlist_symbol");
    var formData = {
        symbol: $("#symbol").val(),
        name: "My Portfolio"
    }

     //$("#btn-search").prop("disabled", true);

    $.ajax({
        type: "POST",
        contentType: "application/json",
        url: "/api/v1/AddSymbolToWatchlist",
        data: JSON.stringify(formData),
        dataType: 'json',
        success: function (result) {
            if(result.status=="Done") {
                $('#feedback').html(result.data.symbol +" added.");
            }
            else {
                $('#feedback').html("<strong>Error</strong>");
            }
            console.log("ERROR: ",e);
        },
        error: function (e) {
            alert("Error!")                    
            console.log("ERROR: ",e);
        }
    });

    // Reset FormData after Posting
    resetData();
}

当我单击该按钮时,我收到 Spring Boot 错误:

已解决 [org.springframework.http.converter.HttpMessageNotReadableException: JSON解析错误:空;嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:不适用 [来源: (PushbackInputStream);行:1,列:11](通过参考链: net.tekknow.moneymachine.model.Watchlist["symbol"])]

我怀疑由于模型包含复合键,表单数据没有正确映射到 Watchlist.java 模型,如下所示:

@Entity
@Table(name = "watchlist")
public class Watchlist {
    @EmbeddedId
    public WatchlistId watchlistId;
    
 
    public String getSymbol() {
        return watchlistId.getSymbol();
    }
    public void setSymbol(String symbol) {
        watchlistId.setSymbol(symbol);
    }

    public String getName() {
        return watchlistId.getName();
    }
    public void setName(String watchlistName) {
        watchlistId.setName(watchlistName);
    }
    
    public String toString() {
        return "watchlist:symbol=" +getSymbol() +", name="+getName();
    }
}

其中 watchlistId 包含符号和名称,如下所示:

@Embeddable
public class WatchlistId implements Serializable {
    @Column(name="symbol")
    private String symbol;
    
    @Column(name="name")
    private String name;
    
    WatchlistId() {     
    }

    WatchlistId(String symbol, String name) {
        this.symbol = symbol;
        this.name = name;
    }
    
    public String getSymbol() {
        return symbol;
    }
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
 
        if (o == null || getClass() != o.getClass()) return false;
 
        WatchlistId that = (WatchlistId) o;
        return Objects.equals(symbol, that.symbol) && Objects.equals(name, that.name);
    }
 
    @Override
    public int hashCode() {
        return Objects.hash(symbol, name);
    }   
}

这是处理请求的 Spring Boot 控制器:

@PostMapping("/AddSymbolToWatchlist")
@ResponseBody
public AddWatchlistSymbolResponse addSymbolToWatchlist(@RequestBody Watchlist watchlist){
    System.out.println("made it to AddWatchlistSymbolResponse");
    // Create Response Object
    AddWatchlistSymbolResponse response = new AddWatchlistSymbolResponse("Done", watchlist);
    return response;
}

AddWatchlistSymbolResponse 类如下所示:

public class AddWatchlistSymbolResponse {
      private String status;
      private Object data;
      
      public AddWatchlistSymbolResponse(){
        
      }
      
      public AddWatchlistSymbolResponse(String status, Object data){
        this.status = status;
        this.data = data;
      }
     
      public String getStatus() {
        return status;
      }
     
      public void setStatus(String status) {
        this.status = status;
      }
     
      public Object getData() {
        return data;
      }
     
      public void setData(Object data) {
        this.data = data;
      }
}

建议?

【问题讨论】:

    标签: javascript java spring spring-boot


    【解决方案1】:

    我想通了。我将控制器更改为:

    @PostMapping(value = "/AddSymbolToWatchlist")
    @ResponseBody
    public WatchlistIdResponse addSymbolToWatchlist(@RequestBody WatchlistId watchlistId){
        System.out.println("made it to AddWatchlistSymbolResponse");
        watchlistService.addSymbolToWatchlist(watchlistId);
        // Create Response Object
        WatchlistIdResponse response = new WatchlistIdResponse("Done", watchlistId);
        return response;
    }
    

    并为 WatchlistId 创建了一个名为 WatchlistIdResponse.java 的单独响应:

    package net.tekknow.moneymachine.model;
    
    public class WatchlistIdResponse {
        private String status;
        private Object data;
    
        public WatchlistIdResponse() {
    
        }
    
        public WatchlistIdResponse(String status, Object data) {
            this.status = status;
            this.data = data;
        }
    
        public String getStatus() {
            return status;
        }
    
        public void setStatus(String status) {
            this.status = status;
        }
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    }
    

    原因是 Watchlist 类只包含 WatchlistId 属性。 WatchlistId 包含构成复合索引的符号和名称属性。

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      相关资源
      最近更新 更多