2017-04-20 64 views
0

我試圖通過REST Web服務將數據從數據庫檢索到移動應用程序。我設法做出了一些基本的功能,但是當我嘗試添加功能時,我遇到了問題。例如,我希望能夠通過他們的ID和他們的名字找到「客戶」。當我有兩個Get方法,一個使用「/ {id}」,另一個使用「/ {name}」時,應用程序不知道要使用什麼。我能做些什麼來按名稱搜索? 這是來自Web服務的控制器。如何在Controller中使用不同的GET方法Spring

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

這是從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); 
} 

的服務的話,這是我用名字來調用服務的功能。當/ web服務控制器中的/ name和/ id函數都是空的,但是當其中一個被註釋掉時,response.body將會爲空。

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

希望我已經讓自己明白了。請詢問是否有不清楚的東西或您需要更多信息。

回答

0

用不同的路徑區分URL,這也會使它們更加RESTful。

按名稱搜索:

/customers/names/{name} 

按ID搜索:

/customers/ids/{id} 

在未來你可能要添加其他搜索,也許是城市:

/customers/cities/{city} 
+0

這工作!謝謝! – Ermehtar

0

你的控制器有不明確的處理程序方法映射,因此在調用端點時,您將實際得到異常。通過創建不同的映射來解決這個問題,以便通過id獲取並按名稱獲取。

0

資源由其PATH(而不是它的參數)唯一標識。因此,有是同一個路徑少的資源:"customers/"

您可以創建兩個不同的資源,如:

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

也可以使一個資源與許多請求參數: @RequestMapping(value = "/get", method = RequestMethod.GET) public ResponseEntity<Customer> get(@RequestParam ("id") Long id, @RequestParam ("name") String name)

1

您的休息時間充分的設計可以提高。我建議定義是這樣的:

新:

/customers/new 

這是不正確的,在寧靜的資源創造應該由方法類型來定義。我的建議是:

/customers with POST method. 

按ID搜索:

/customers/{id} 

這是正確的,在寧靜的資源應該是通過使用路徑變量ID訪問。

按名稱搜索:

/customers/{name} 

這是不正確的,在這裏你都quering的客戶資源,因此,你應該使用查詢參數,我的建議是:

/customers?name=<<name>> 

如果你有多個查詢方法,你會得到一個衝突,因爲你在一個具有相同路徑的控制器中不能有多個GET方法。所以,你可以修改@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) { 
    ... 
} 
相關問題