Запрос REST GET не отображает список <object>как JSON - PullRequest
0 голосов
/ 02 марта 2019

Я новичок в Spingboot, делаю демонстрацию (пример) очень простого приложения для отображения списка классов в виде JSON, но я получаю ошибку.Что я упустил в своей конфигурации / зависимостях?

Мой 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>

Структура моих каталогов: Application Directories structure

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

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

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

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);
    }

}

Я использую IntelliJ 2018.3, JDK 1.8.0_144 и Springboot.Когда я запускаю сервер и перехожу на «localhost: 8080 / bookings / all» вместо JSON, я получаю следующее: JSON is not displayed

Почему список не отображается как JSON?Чего мне не хватает?

Я ожидаю получить что-то вроде следующего: Expected result- JSON

Буду признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Ваш метод BookingController#getAll() возвращает List, который будет преобразован в JSON полезную нагрузку.На стороне клиента вы увидите его как JSON.Он не будет магически отображаться как переменная JSONObject на странице HTML.Для этого вам понадобится шаблонный движок .Вы также можете использовать статический файл index.html для воспроизведения с API на стороне клиента.Гораздо проще начать с.

Для этого вам нужно добавить в 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>

К application.properties файлу добавить строку ниже:

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

Этого должно быть достаточно, чтобы увидеть под http://localhost:8080/ нижнее содержание: enter image description here

Когда вы работаете с prices и, как правило, money в Javaвсегда используйте BigDecimal.Я исправил ваш 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));
    }
}

Ваш конструктор контроллера может выглядеть следующим образом:

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));
}

В примере inex.html Я использовал axiosи bootstrap библиотеки.

0 голосов
/ 02 марта 2019

Класс HotelBooking должен быть JavaBean.Для того, чтобы он был один, он должен:

  1. Иметь конструктор без параметров
  2. Иметь методы получения и установки для всех свойств

Итак,если вы измените свой класс на этот:

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;
    }
}

Он должен работать как положено.

Кстати. НЕ используйте double тип для денежных значений.Вместо этого используйте java.math.BigDecimal.

...