如何从给定参数检索查询?

时间:2018-07-16 08:44:20

标签: spring rest spring-boot

我最近开始在工作中学习Spring Boot和Spring RESTful。我可以在春季REST项目中打印“ Hello world”。我还使用了收藏集,并能够显示城市名称。现在,我需要使用户能够请求一个城市,应用程序将仅在该城市上检索该城市的数据。

我知道我必须使用RequestMapping,但是我似乎不太了解很多技术术语。这不是您要做我的工作的要求,我要的只是帮助。我会学到很多更好的东西,但是我的公司给了我不到一个星期的时间来演示它,并且我已经学习了Spring的基础知识,所以我必须在旅途中学习。 >

感谢您的帮助。

我将它们放在单独的主文件夹中,而不是单独的软件包。

此类提供了请求的数据。

package com.weatherreport.demo;

import java.util.ArrayList;
import java.util.List;


import org.springframework.http.ResponseEntity;
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;

@RestController

public class WeatherResource
{
    @RequestMapping("weather")

    public List<Weather> getWeather()
    {
        List<Weather> weather=new ArrayList<>();

        Weather a1=new Weather();
        Weather a2=new Weather();
        Weather a3=new Weather();
        Weather a4=new Weather();
        Weather a5=new Weather();
        Weather a6=new Weather();

        a1.setCity("Timbuktu");
        a1.setMaxTemp(38);
        a1.setMinTemp(15);
        a1.setRainfall(3.5);
        a1.setWindspeed((float) 11.5);
        a1.setHumidity(29);


        a2.setCity("London");
        a2.setMaxTemp(12);
        a2.setMinTemp(2);
        a2.setRainfall(12.5);
        a2.setWindspeed((float) 1.5);
        a2.setHumidity(12);




        a3.setCity("Delhi");
        a3.setMaxTemp(38);
        a3.setMinTemp(29);
        a3.setRainfall(0.2);
        a3.setWindspeed((float) 19.5);
        a3.setHumidity(9);


        a4.setCity("Mawsynram");
        a4.setMaxTemp(22);
        a4.setMinTemp(16);
        a4.setRainfall(358.5);
        a4.setWindspeed((float) 91.5);
        a4.setHumidity(96);


        a5.setCity("Wellington");
        a5.setMaxTemp(12);
        a5.setMinTemp(9);
        a5.setRainfall(31.5);
        a5.setWindspeed((float)44);
        a5.setHumidity(85);




        weather.add(a1);
        weather.add(a2);
        weather.add(a3);
        weather.add(a4);
        weather.add(a5);



        return weather;
    }


}

这是定义变量及其getter设置程序的基本类。

package com.weatherreport.demo;

public class Weather
{
    private String city;
    private int maxTemp;
    private int minTemp;
    private float rainfall;
    private float windspeed;
    private int humidity;
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public int getMaxTemp() {
        return maxTemp;
    }
    public void setMaxTemp(int maxTemp) {
        this.maxTemp = maxTemp;
    }
    public int getMinTemp() {
        return minTemp;
    }
    public void setMinTemp(int minTemp) {
        this.minTemp = minTemp;
    }
    public float getRainfall() {
        return rainfall;
    }
    public void setRainfall(double d) {
        this.rainfall = (float) d;
    }
    public float getWindspeed() {
        return windspeed;
    }
    public void setWindspeed(float windspeed) {
        this.windspeed = windspeed;
    }
    public int getHumidity() {
        return humidity;
    }
    public void setHumidity(int humidity) {
        this.humidity = humidity;
    }



}

未对SpringBootApplication类进行任何更改。

现在,当我通过POSTman发送GET请求时,我将获得集合中存在的所有数据。取而代之的是,我想要的是让用户能够输入城市,并检查所需的城市是否在数据库中。如果是,它将仅显示该特定城市的数据。

我知道这种类型的问题令人厌烦。但是我被困在一块石头和一块坚硬的地方之间,可以使用所有一点帮助。谢谢。

编辑

我终于做到了。谷歌搜索和学习一些途中。

这些是我的要求:我必须在集合中进行一些数据处理。然后,我不得不检索所需城市的数据。我使用了Web依赖,仅此而已。

首先,创建一个模型类,在模型类中定义所有必需的参数。在上面检查上述课程。

我选择了丑陋的方式,而不是将存储库和控件类分开。无论如何,这是控制/资源类的代码。

@RestController
public class WeatherResource
{

    @RequestMapping(value = "/weather", method = RequestMethod.GET) //This will get the entire data.
    public List getWeather()
    {
        List<Weather> listOfCityWeather = new ArrayList();
        listOfCityWeather=createCityWeatherList();
        return listOfCityWeather;
    }

    @RequestMapping(value = "/weather/{city}", method = RequestMethod.GET) // Gets the data for a specific city
    public Weather getWeatherByCity(@PathVariable String city)
    {

        List<Weather> listOfCityWeather = new ArrayList();
        listOfCityWeather=createCityWeatherList();

        for (Weather weather: listOfCityWeather) {
            if(weather.getCity().equalsIgnoreCase(city))
            {

                return weather;

            }

        }


        return null;
    }



        public List createCityWeatherList()
        {

            List<Weather> listOfCityWeather=new ArrayList<>();

            Weather a1=new Weather();



            a1.setCity("Timbuktu");
            a1.setMaxTemp(38);
            a1.setMinTemp(15);
            a1.setRainfall(3.5);
            a1.setWindspeed((float) 11.5);
            a1.setHumidity(29);


            //Initialise the List as required. I have provided an example.


            listOfCityWeather.add(a1);


            return listOfCityWeather;
        }



}

感谢所有人,尤其是@ g00glen00b对我的帮助。

1 个答案:

答案 0 :(得分:0)

首先,如果要使用数据库,则需要对代码库进行一些更改。如果要使用SQL数据库(1),则可以使用Spring Data JPA和内存数据库(例如HSQLDB或H2)进行开发/测试。要使用这些依赖关系,您需要添加一些依赖关系,例如使用Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
</dependency>
  

(1)即使您不打算使用SQL数据库,Spring Data项目的目标是为所有数据源提供一致的API,因此您可以进行更改您的代码很容易。

此后,您需要更改您的Weather类,使其成为有效的JPA实体(实体类是数据库中表的Java表示形式)。您必须在这里定义的一件事是您的主键,它应该是唯一的。例如,在这种情况下,它可能是城市:

@Entity // Add this to declare your Weather class as an entity
public class Weather {
    @Id // Add this to define your city as the primary key
    private String city;
    private int maxTemp;
    private int minTemp;
    private float rainfall;
    private float windspeed;
    private int humidity;

    // Getters + Setters
}

现在有了实体,您可以创建一个Spring数据存储库,该存储库提供用于访问/修改数据库中数据的方法。 Spring Data将为您完成大部分工作,您要做的就是创建一个从JpaRepository开始的新接口:

public interface WeatherRepository extends JpaRepository<Weather, String> {

}
  

传递给JpaRepository<Weather, String>的泛型是您的实体类和主键的类型(这是您的城市,所以它是String)。

此后,您可以移动用于创建所有天气记录的逻辑,以便在您启动应用程序时创建它们。为此,我们可以实现ApplicationRunner接口:

@Component
public class WeatherInitializer implements ApplicationRunner {
    private WeatherRepository repository;

    public WeatherInitializer(WeatherRepository repository) {
        this.repository = repository;
    }

    @Override
    public void run(ApplicationArguments args) {
        Weather a1=new Weather();
        Weather a2=new Weather();
        // Initialize the weather objects like you did in your controller

        // Save all weather records on startup
        repository.saveAll(Arrays.asList(a1, a2, a3, a4, a5));
    }
}

Spring将自动创建此类的实例,在应用程序启动时注入WeatherRepository并调用run()方法。

现在,您可以重构控制器以使用存储库:

@RestController
@RequestMapping("/weather") // All endpoints will have '/weather' in them, so you can put it here
public class WeatherResource {
    private WeatherRepository repository;

    public WeatherResource(WeatherRepository repository) {
        this.repository = repository;
    }

    @GetMapping // You can use GetMapping to only allow GET calls
    public List<Weather> getWeather() {
        return repository.findAll(); // This should replace your original implementation
    }
}

现在,对于参数化调用,您必须决定如何发送这些参数,例如:

  • 您可以使用查询参数(例如/weather?city=Timbuktu
  • 您可以使用路径参数(例如/weather/Timbuktu
  • ...

如果要使用路径参数,可以使用@PathVariable批注。因此,例如,您可以将此方法添加到WeatherResource

@GetMapping("/{city}")
public Weather getWeather(@PathVariable String city) {
    return repository.findById(city);
}

通过在路径中使用{city}占位符并使用@PathVariable批注,Spring将能够将城市名称传递给您的方法。之后,您可以使用repository.findById()方法获取特定城市的天气。

如果您希望代替使用查询参数,则不需要{city}占位符,而必须将@PathVariable注释替换为@RequestParam注释:

@GetMapping
public Weather getWeather(@RequestParam String city) {
    return repository.findById(city);
}