简体   繁体   English

如何在Controller Java Spring中使用不同的GET方法

[英]How to have to different GET methods in Controller Java Spring

I'm trying to retrieve data from a database to an mobile app through a REST web service. 我正在尝试通过REST Web服务将数据从数据库检索到移动应用程序。 I've managed to make some basic functions but when I try to add functions I run into problems. 我设法做了一些基本功能,但是当我尝试添加功能时,我遇到了问题。 For example I want to be able to find "Customers" by their Id and their name. 例如,我希望能够通过其ID和名称查找“客户”。 When I have two Get methods, one with "/{id}" and one with "/{name}" the app does not know what to use. 当我有两个Get方法时,一个带有“ / {id}”的方法和一个带有“ / {name}”的方法,该应用程序不知道使用什么方法。 What can I do to search by name? 我该怎么做才能按名称搜索? This is the controller from the web service. 这是来自Web服务的控制器。

package com.example;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/customers")
public class CustomerController {
private CustomerRepository repository;

@Autowired
public CustomerController(CustomerRepository repository) {
    this.repository = repository;
}

@RequestMapping(value = "/{name}", method = RequestMethod.GET)
public ResponseEntity<Customer> get(@PathVariable("name") String name) {
    Customer customer = repository.findByName(name);
    if (null == customer) {
        return new ResponseEntity<Customer>(HttpStatus.NOT_FOUND);
    }
    return new ResponseEntity<Customer>(customer, HttpStatus.OK);
}

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Customer> get(@PathVariable("id") Long id) {
    Customer customer = repository.findOne(id);
    if (null == customer) {
        return new ResponseEntity<Customer>(HttpStatus.NOT_FOUND);
    }
    return new ResponseEntity<Customer>(customer, HttpStatus.OK);*
}

@RequestMapping(value = "/new", method = RequestMethod.POST)
public ResponseEntity<Customer> update(@RequestBody Customer customer) {
    repository.save(customer);
    return get(customer.getName());
}

@RequestMapping
public List<Customer> all() {
    return repository.findAll();
}
}

This is the service from the android application 这是来自android应用程序的服务

package com.ermehtar.poppins;

import java.util.List;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.PATCH;
import retrofit2.http.POST;
import retrofit2.http.Path;

public interface CustomerService {
@GET("customers")
Call<List<Customer>> all();

@GET("customers/{id}")
Call<Customer> getUser(@Path("id") Long id);

@GET("customers/{name}")
Call<Customer> getUser(@Path("name") String name);

@POST("customers/new")
Call<Customer> create(@Body Customer customer);
}

Then this is the function that I use to call the service by name. 这就是我用来按名称调用服务的函数。 The response.body will be null when both /name and /id functions are in the web service controller but when one of them is commented out this works just fine. 当/ name和/ id函数都在Web服务控制器中时,response.body将为null,但是当其中之一被注释掉时,此方法就可以正常工作。

findUsernameButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Call<Customer> createCall = service.getUser("John");
            createCall.enqueue(new Callback<Customer>() {
                @Override
                public void onResponse(Call<Customer> _, Response<Customer> resp) {
                    findUsernameButton.setText(resp.body().name);
                }

                @Override
                public void onFailure(Call<Customer> _, Throwable t) {
                    t.printStackTrace();
                    allCustomers.setText(t.getMessage());
                }
            });
        }
    });

Hope I've made myself understandable. 希望我让自己可以理解。 Please ask if there is something unclear or you need more information. 请询问是否有不清楚的地方,或者您需要更多信息。

Your restful design can improve. 您的宁静设计可以改善。 I suggest defining something like this: 我建议定义这样的内容:

New: 新:

/customers/new

This is not correct, in restful a resource creation should be defined by method type. 这是不正确的,在静态状态下,应该通过方法类型定义资源创建。 I suggest this: 我建议这样:

/customers with POST method.

Search by ID: 依编号搜寻:

/customers/{id}

This is correct, in restful a resource should be access by id using path variable. 这是正确的,在静态状态下,应该使用路径变量通过id访问资源。

Search by name: 按名称搜索:

/customers/{name}

This is not correct, here you are querying the customers resource, so, you should use query params, I suggest this: 这是不正确的,在这里您要查询客户资源,因此,应该使用查询参数,我建议这样做:

/customers?name=<<name>>

If you have multiple query methods, you will get a conflict because you cannot have more than one GET method in a controller with the same path. 如果您有多种查询方法,则将产生冲突,因为在具有相同路径的控制器中不能有多个GET方法。 So, you can modify @RequestMapping to explicit assert which query params are required like this: 因此,您可以修改@RequestMapping以显式声明需要哪些查询参数,如下所示:

@RequestMapping(value = "/", method = RequestMethod.GET, , params = "name")
public ResponseEntity<Customer> getByName(@RequestParam("name") String name) {
    ...
}

@RequestMapping(value = "/", method = RequestMethod.GET, , params = "lastname")
public ResponseEntity<Customer> getByLastname(@RequestParam("lastname") String lastname) {
    ...
}

Differentiate the URLs with a different path which will also make them more RESTful. 用不同的路径区分URL,这也将使它们更加RESTful。

Search by name: 按名称搜索:

/customers/names/{name}

Search by ID: 依编号搜寻:

/customers/ids/{id}

In the future you might want to add another search, perhaps by city: 将来,您可能想添加另一个搜索,也许是按城市:

/customers/cities/{city}

Your controller has ambiguous handler methods mapped so when calling the endpoint you will actually get an exception. 您的控制器映射了模糊的处理程序方法,因此在调用端点时,您实际上会得到一个异常。 Fix this by creating different mappings for get by id and get by name. 通过为id和id获取创建不同的映射来解决此问题。

Resource is uniquely identified by its PATH (and not by it's params). 资源由其PATH唯一标识(而不是由参数确定)。 So, there're few resources with the same PATH: "customers/" 因此,很少有具有相同PATH的资源: "customers/"

You can create two different resources like: 您可以创建两个不同的资源,例如:

  • @RequestMapping(value = "/id", method = RequestMethod.GET)
  • @RequestMapping(value = "/name", method = RequestMethod.GET)

Or you can make one resource with many request parameters: @RequestMapping(value = "/get", method = RequestMethod.GET) public ResponseEntity<Customer> get(@RequestParam ("id") Long id, @RequestParam ("name") String name) 或者,您可以使一个资源具有许多请求参数: @RequestMapping(value = "/get", method = RequestMethod.GET) public ResponseEntity<Customer> get(@RequestParam ("id") Long id, @RequestParam ("name") String name)

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

相关问题 如何让控制器端点在java spring中获取两个不同的对象? - How to make controller endpoint to get two different objects in java spring? 如何在弹簧控制器中应用于验证器的特定方法的不同行为 - How to apply in validator different behaviours for particular methods in spring Controller 如何在Java Spring Controller中获取XML - How to get the XML in Java spring controller 如何在Spring MVC中调用控制器方法 - How to invoke controller methods in Spring MVC 如何测试Spring RESTful MVC控制器方法? - How to test spring RESTful MVC controller methods? 如何为不同的方法使用不同的 spring 事务 - How to use different spring transactions for different methods 如何在Spring MVC Controller的Java Map中使用子域获取JSON字符串 - How to get JSON String with Subdomain in Java Map at Spring MVC Controller 如何使Ajax在Spring MVC中获得对Java控制器的文本调用? - How to make ajax get call for text to Java controller in Spring MVC? Spring Mvc:在同一Controller中跨不同方法获取会话属性 - Spring Mvc: getting session attributes accross different methods in the same Controller 如何在GET和POST请求的Spring控制器方法之间共享信息? - How to share information between Spring controller methods from GET and POST requests?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM