简体   繁体   English

REST GET 请求不显示列表<object>作为 JSON

[英]REST GET request doesn't show List<object> as JSON

I am new to Spingboot, doing a demo (an example) of a very simple application to display a list of classes as a JSON, but I get an error.我是 Spingboot 的新手,正在制作一个非常简单的应用程序的演示(示例),以将类列表显示为 JSON,但出现错误。 What did I miss in my configuration/dependencies?我在配置/依赖项中遗漏了什么?

My pom.xml:我的 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.1.3.RELEASE</version>
          <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>com.beniregev</groupId>
     <artifactId>booking-demo</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>booking-demo</name>
     <description>Demo project for Spring Boot</description>

     <properties>
          <java.version>1.8</java.version>
     </properties>

     <dependencies>
          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
          </dependency>
          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
          </dependency>
          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
          </dependency>
          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
          </dependency>

          <dependency>
                <groupId>org.hsqldb</groupId>
                <artifactId>hsqldb</artifactId>
                <scope>runtime</scope>
          </dependency>
          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
          </dependency>
     </dependencies>

     <build>
          <plugins>
                <plugin>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
          </plugins>
     </build>

 </project>

My directories structure:我的目录结构: 应用程序目录结构

DemoController.java - this is working ("localhost:8080/hello") DemoController.java - 这是有效的(“localhost:8080/hello”)

package com.beniregev.bookingdemo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @RequestMapping("/hello")
    public String hello() {
        return "Hello";
    }
}

HotelBooking.java酒店预订.java

package com.beniregev.bookingdemo;

public class HotelBooking {
    private String hotelName;
    private double pricePerNight;
    private int numberOfNights;

    public HotelBooking(String hotelName, double pricePerNight, int numberOfNights) {
        this.hotelName = hotelName;
        this.pricePerNight = pricePerNight;
        this.numberOfNights = numberOfNights;
    }

    public String getHotelName() {
        return hotelName;
    }

    public double getPricePerNight() {
        return pricePerNight;
    }

    public int getNumberOfNights() {
        return numberOfNights;
    }

    public double getTotalPrica() {
        return pricePerNight * numberOfNights;
    }
}

BookingController.java预订控制器.java

package com.beniregev.bookingdemo;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value="/bookings")
public class BookingController {
    private List<HotelBooking> bookings;

    public BookingController() {
        bookings = new ArrayList<>();

        bookings.add(new HotelBooking("Marriot", 200.50, 3));
        bookings.add(new HotelBooking("Novotel", 140.74, 1));
        bookings.add(new HotelBooking("Ibis", 90.0, 4));
        bookings.add(new HotelBooking("Hilton", 150.60, 5));
    }

    @RequestMapping(value = "/all", method = RequestMethod.GET)
    public List<HotelBooking> getAll() {
        return bookings;
    }
}

BookingDemoApplication.java预订演示应用程序.java

package com.beniregev.bookingdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BookingDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(BookingDemoApplication.class, args);
    }

}

I am using IntelliJ 2018.3, JDK 1.8.0_144 and Springboot.我正在使用 IntelliJ 2018.3、JDK 1.8.0_144 和 Springboot。 When I am running the server and go to "localhost:8080/bookings/all" instead of a JSON I get the following:当我运行服务器并转到“localhost:8080/bookings/all”而不是 JSON 时,我得到以下信息: 不显示 JSON

Why the List is not displayed as JSON?为什么列表不显示为 JSON? What am I missing?我错过了什么?

I am expecting to receive something like the following:我期待收到如下内容: 预期结果 - JSON

I will appreciate any help.我将不胜感激任何帮助。

Your BookingController#getAll() method returns List which will be converted to JSON payload.您的BookingController#getAll()方法返回将转换为JSON负载的List ON client side you will see it as a JSON .在客户端,您将看到它作为JSON It will not appear magically as JSONObject variable in HTML page.它不会像JSONObject变量那样神奇地出现在HTML页面中。 To do that you need template engine .为此,您需要模板引擎 You can also use static index.html file to play with your API on client side.您还可以使用静态index.html文件在客户端使用您的API It is much simpler to start from.从头开始要简单得多。

To do that, you need to add to resources/static folder index.html file with content like below:为此,您需要将内容如下添加到resources/static文件夹index.html文件中:

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <title>Hotel bookings</title>
</head>
<body>
<h1>Hotel bookings</h1>
<table class="table">
    <thead>
    <tr>
        <th scope="col">#</th>
        <th scope="col">Name</th>
        <th scope="col">Number of nights</th>
        <th scope="col">Price per night</th>
        <th scope="col">Total price</th>
    </tr>
    </thead>
    <tbody class="bookingsBody"></tbody>
</table>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
        integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
        crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
        integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
        crossorigin="anonymous"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    function laodAllHotelBookings() {
        var url = '/bookings/all/';
        var headers = {
            headers: {
                'Content-Type': 'application/json'
            }
        };
        axios.get(url, headers).then(res => {
            let bookingsBody = $('.bookingsBody');
            let data = res.data;
            $.each(Object.keys(data), function (index, key) {
                let item = data[key];
                var row = $('<tr>');
                row.append($('<th>').text(index));
                row.append($('<td>').text(item.hotelName));
                row.append($('<td>').text(item.pricePerNight));
                row.append($('<td>').text(item.numberOfNights));
                row.append($('<td>').text(item.totalPrice));

                bookingsBody.append(row);
            })
        }).catch(error => {
            console.log("error", error);
            const errorMsg = 'There was an error fetching the menu';
            console.log(errorMsg);
        });
    }

    laodAllHotelBookings();
</script>
</body>
</html>

To application.properties file add below line:application.properties文件中添加以下行:

spring.resources.static-locations[0]=file:src/main/resources/static/

It should be enough to see under http://localhost:8080/ below content:http://localhost:8080/下看到下面的内容应该就够了: 在此处输入图片说明

When you are working with prices and generally money in Java always use BigDecimal .当您在Java中处理prices和通常的money ,总是使用BigDecimal I have fixed your POJO :我已经修复了你的POJO

import java.math.BigDecimal;

public class HotelBooking {
    private String hotelName;
    private BigDecimal pricePerNight;
    private int numberOfNights;

    public HotelBooking(String hotelName, BigDecimal pricePerNight, int numberOfNights) {
        this.hotelName = hotelName;
        this.pricePerNight = pricePerNight;
        this.numberOfNights = numberOfNights;
    }

    public String getHotelName() {
        return hotelName;
    }

    public BigDecimal getPricePerNight() {
        return pricePerNight;
    }

    public int getNumberOfNights() {
        return numberOfNights;
    }

    public BigDecimal getTotalPrice() {
        return pricePerNight.multiply(BigDecimal.valueOf(numberOfNights));
    }
}

Your controller constructor could look like below:您的控制器构造函数可能如下所示:

public BookingController() {
    bookings = new ArrayList<>();

    bookings.add(new HotelBooking("Marriot", new BigDecimal("200.50"), 3));
    bookings.add(new HotelBooking("Novotel", new BigDecimal("140.74"), 1));
    bookings.add(new HotelBooking("Ibis", new BigDecimal("90.0"), 4));
    bookings.add(new HotelBooking("Hilton", new BigDecimal("150.60"), 5));
}

In example inex.html I used axios and bootstrap libraries.inex.html示例中,我使用了axiosbootstrap库。

Class HotelBooking needs to be a JavaBean.HotelBooking需要是 JavaBean。 In order for it to be one, it must:为了使它成为一个,它必须:

  1. Have an constructor with no parameters有一个没有参数的构造函数
  2. Have getter AND setters for all properties所有属性都有 getter 和 setter

So, if you change your class to this:所以,如果你把你的班级改成这样:

package com.beniregev.bookingdemo;

public class HotelBooking {
    private String hotelName;
    private double pricePerNight;
    private int numberOfNights;

    public HoterBooking() 
    {
    }

    public HotelBooking(String hotelName, double pricePerNight, int numberOfNights) {
        this.hotelName = hotelName;
        this.pricePerNight = pricePerNight;
        this.numberOfNights = numberOfNights;
    }

    public String getHotelName() {
        return hotelName;
    }

    public void setHotelName(String val) {
        this.hotelName = val;
    }

    public double getPricePerNight() {
        return pricePerNight;
    }

    public void setPricePerNight(double val) {
        this.pricePerNight = val;
    }

    public int getNumberOfNights() {
        return numberOfNights;
    }

    public void setNumberOfNights(int val) {
        this.numberOfNights = val;
    }

    public double getTotalPrica() {
        return pricePerNight * numberOfNights;
    }
}

It should work as expected.它应该按预期工作。

By the way.顺便一提。 DO NOT use double type for money values.不要对货币值使用double型。 Use java.math.BigDecimal instead.请改用java.math.BigDecimal

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM