他のサーバへのリクエスト機能の実装
今日SpringサーバからPythonサーバにリクエストを送信します.
一人で協力する仮定の下で...シミュレーションをします!
サーバ間の関係の理解
Gitブランチの作成
テストの準備
製品コントローラMvcテスト
DBTest-selectテスト
Git Merge
🧐サーバ間の関係の理解
ユーザーが検索を行います. Spring Serverは、データベースを検索値でクエリーします. DBにデータが存在する場合、ユーザに直接応答する.ない場合は、PythonサーバにHttpリクエストを送信します. リクエストを受信したPythonサーバは、データを収集します. Python Serverは、収集したデータをデータベースに挿入します. Insertが完了すると、Javaサーバに「check:true」が送信されます. Javaサーバは、ユーザデータに応答するためにDBを再クエリします. ここでは、データベースをクエリーします.データがなければ、PythonサーバにHttpリクエストを送信します.
🧐Gitブランチの作成
ユーザー要求がコントローラに正しく送信されたかどうかをテストします. ユーザの要求がデータベースによって正常に選択されたかどうかをテストする . DBのデータに異なる論理があるかどうかをテストします.
🧐ProductControllerTest
ProductControlにマッピングし、論理を追加します.
成功!!
jsonに正しく変換します.
🧐DBTest-selectテスト
MockMvcのConstructor問題 Spring Data Jpa-Naming問題(Camel->Snake) このエラーに関する記事をアップロードしましょう!!
https://tech.devgd.com/12 https://n1tjrgns.tistory.com/221
一人で協力する仮定の下で...シミュレーションをします!
🚗目次
サーバ間の関係の理解
Gitブランチの作成
テストの準備
製品コントローラMvcテスト
DBTest-selectテスト
Git Merge
🧐サーバ間の関係の理解
まずサーバー間の関係を見てみましょう.
🧐Gitブランチの作成
まずGitブランチを作成します.
機能実装では、「feature/request to python server with http-chanYoungho」が生成されます.
🌈ブランチの作成
Developブランチを除去し、ブランチを作成します.
🌈Upstream設定
🌈git checkout
いいですね.今からコーディングを始めましょう
🧐テストの準備
まず、テストで実現する内容を見てみましょう.
まず、テストで実現する内容を見てみましょう.
🌈testクラスの作成
* Test를 Controller 테스트, Select & Request 테스트 2개로 한다.
* Controller 테스트 : ProductControllerTest.java
* Select & Request 테스트 : DBTest.java
🌈test正常運転確認!
*ProductController.java - void queryParameterTest(){}
![](https://media.vlpt.us/images/jkijki12/post/f3f32ac2-2d50-4d03-af59-ba83726576ae/1.PNG)
* DBTest.java - void getData(){}
![](https://media.vlpt.us/images/jkijki12/post/4d251785-d70f-41a8-b2d1-87568cedd0d0/3.PNG)
各テストを順番に見ましょう.🧐ProductControllerTest
このテストはMVCを駆動する必要がある.だからMockMvcを利用しよう!
コードは次のとおりです.
@SpringBootTest
@AutoConfigureMockMvc
public class ProductControllerTest {
@Autowired // Autowired 없으면 아래에 있는 BeforeEach로 MockMvc를 생성해주어야 한다.
private MockMvc mockMvc;
/*
@BeforeEach로 MockMvc를 생성할 경우,
해당 컨트롤러에 존재하는 @Autowired 객체를 제대로 못읽어온다.
*/
/*
@BeforeEach //테스트 시작하기 전에 기초작업
public void before(){ // 보통 before, setup을 메서드명으로 사용한다.
// mock 컨트롤러를 생성해야한다.
mockMvc =
MockMvcBuilders
.standaloneSetup(ProductController.class) // 테스트를 진행할 Controller를 입력
.alwaysExpect(status().isOk()) // 필수 조건, 굳이 없어도 될 듯?
.build();
}
*/
//본격 테스트 메서드
@Test
public void queryParameterTest() throws Exception{
mockMvc.perform( // 컨트롤러를 호출해야한다.
MockMvcRequestBuilders // 보낼 Request를 생성한다.
.get("/products?query=바나나우유") // get 메서드를 이용한다.
.accept(MediaType.ALL)) // 모든 타입을 받는다.
// 여기부터는 받는 값을 테스트한다. status : ok를 예상, 위에서 필수 조건으로 ok 넣어서 무조건 통과할 듯
.andExpect(status().isOk())
// 받는 Response의 body에 content를 json으로 고쳐서 받는 값이랑 비교한다.
.andExpect(content().json("{\"query\":\"바나나우유\"}"));
}
};
もちろん失敗します.どうしたんですか.(実際には、コメントを抜き、コードを正しくリストする必要があります.)
ProductControllerには「/pruducts?query=バナナミルク」のマッピングがないから!
@SpringBootTest
@AutoConfigureMockMvc
public class ProductControllerTest {
@Autowired // Autowired 없으면 아래에 있는 BeforeEach로 MockMvc를 생성해주어야 한다.
private MockMvc mockMvc;
/*
@BeforeEach로 MockMvc를 생성할 경우,
해당 컨트롤러에 존재하는 @Autowired 객체를 제대로 못읽어온다.
*/
/*
@BeforeEach //테스트 시작하기 전에 기초작업
public void before(){ // 보통 before, setup을 메서드명으로 사용한다.
// mock 컨트롤러를 생성해야한다.
mockMvc =
MockMvcBuilders
.standaloneSetup(ProductController.class) // 테스트를 진행할 Controller를 입력
.alwaysExpect(status().isOk()) // 필수 조건, 굳이 없어도 될 듯?
.build();
}
*/
//본격 테스트 메서드
@Test
public void queryParameterTest() throws Exception{
mockMvc.perform( // 컨트롤러를 호출해야한다.
MockMvcRequestBuilders // 보낼 Request를 생성한다.
.get("/products?query=바나나우유") // get 메서드를 이용한다.
.accept(MediaType.ALL)) // 모든 타입을 받는다.
// 여기부터는 받는 값을 테스트한다. status : ok를 예상, 위에서 필수 조건으로 ok 넣어서 무조건 통과할 듯
.andExpect(status().isOk())
// 받는 Response의 body에 content를 json으로 고쳐서 받는 값이랑 비교한다.
.andExpect(content().json("{\"query\":\"바나나우유\"}"));
}
};
@RestController
@Slf4j
@RequiredArgsConstructor
public class ProductController {
//이전 테스트에서 사용했던 Service
@Autowired
private final ProductService productService;
@GetMapping("/products") // 해당 url로 get 매핑한다.
@ResponseBody // body에 return 값을 입력하여 Response 한다.
public HashMap<String, String> getProduct(@RequestParam(value = "query", required = false) String query){
// 쿼리 파라미터로 넘어온 "query"를 @RequestParam으로 받는다.
HashMap<String, String> map = new HashMap<>();
map.put("query", query); //map으로 받는다.
return map; // 그대로 리턴한다. -> jackson이 json으로 수정
}
};
成功!!
jsonに正しく変換します.
🧐DBTest-selectテスト
受信したクエリーでデータを選択するテストを行います.
さらに理解が必要な場合は以下の通りです.
データベースから「クエリー」を選択します.
選択した場合、データがある場合、リストはNULLではありません.
選択すると、データがない場合は、Httpメッセージが生成され、他のサーバに送信されます.
対応する検索語を渡す.その後、他のサーバは「check」:「true」}に応答します.
(別のサーバが作成されました)->その他のサーバによる記事の生成
DBTest.Javaですべてが存在すると仮定してコードを記述する方法を作成しましょう.
🌈テストの作成
DBTest.JAva生成とテスト実施@SpringBootTest
public class DBTest {
@Autowired
private ProductService productService;
@Test
public void getData(){
//given
String query = "바나나우유";
List<Product> list = productService.findByDataType(query);
//when
if(list.isEmpty()){
CommunicatePython communicatePython = new CommunicatePython();
HashMap<String, String> map = communicatePython.createHttpRequestAndSend(query);
Assertions.assertEquals("true", result);
}else{
Assertions.assertNotNull(list);
}
}
};
テストを見てみましょう.
1.クエリーを指定します.
2.検索語でDBで選択し、リストに入れる.
リストがNULLの場合、PythonサーバにDB INSERTリクエストを発行します.
4.PythonサーバがINSERTを完了したら、{"check":"true"}をjsonとして応答します.
5.assertEqualsで「true」をテストします.
6.リストがNULLでない場合、assertNotNullを使用してリストがNULLであるかどうかをテストします.
はい、いつですか.その时はよく知りませんでした.私は国語が話せません.
もちろん失敗します.エラーの原因はSymbolです.
では、必要な相手を記入しましょう!!
🌈Go To Symbolの作成
🔎ProductService.Javaの変更
@Service
@RequiredArgsConstructor
public class ProductService {
@Autowired
private final ProductRepository productRepository;
public List<Product> findByDataType(){
List<Product> productList = productRepository.findByDataType();
return productList;
}
};
🔎CommunicatePython.Javaの作成と実装
public class CommunicatePython {
public void createHttpRequestAndSend(String query){
//필요한 객체 생성
RestTemplate restTemplate = new RestTemplate();
//body 생성
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("query", query);
//header 생성
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// header, body 합치기
HttpEntity<MultiValueMap<String,String>> entity = new HttpEntity<>(params, headers);
// POST 요청 보내고, 응답값을 JSONObject로 받기
JSONObject jsonObject = new JSONObject(restTemplate.postForObject("http://python서버 ip:포트번호/get_data", entity, String.class));
// Json 파싱
String result = jsonObject.getString("check");
return result;
}
};
HTTPを生成しPythonサーバに送信する.そして回答料を受け取ります.
テストしてみましょう.
間違いが爆発した.
もちろんです.
サービス中のRepositoryにfindByDataType()メソッドは存在しないから!
では、Repositoryに行ってfindByDataType()を作成しましょう.
🔎ProductRepository.Javaの変更
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByDataType(String data_type);
};
いくつかのエラーのため、メソッド名はすべて変更されました.
Data_type -> DataType
Spring Data JPA参考になりました!
もう一度テストします.
うん.間違いがあった...理由は.
このリクエストは拒否されました.
他のサーバーをつけずに回りました.サーバーを起動しない
サーバーを実行し、テストします.
成功
他のサーバもqueryパラメータを正しくスキップしました.
🔎データがあれば
現在mysqlには「緑茶」のデータがあります.
テストでqueryを修正して、もう一度テストします!
テストに合格しました!
🧐Git Merge
機能が実現しました.
提出する
「開発」に移動
git checkout develop
merge
git merge features/request_to_python_server_with_http-ChaYoungHo
マージ完了
📋の最後の部分
2台のサーバをテスト中に多くのエラーが発生しました.経験した誤りは以下の通りである.
@SpringBootTest
public class DBTest {
@Autowired
private ProductService productService;
@Test
public void getData(){
//given
String query = "바나나우유";
List<Product> list = productService.findByDataType(query);
//when
if(list.isEmpty()){
CommunicatePython communicatePython = new CommunicatePython();
HashMap<String, String> map = communicatePython.createHttpRequestAndSend(query);
Assertions.assertEquals("true", result);
}else{
Assertions.assertNotNull(list);
}
}
};
@Service
@RequiredArgsConstructor
public class ProductService {
@Autowired
private final ProductRepository productRepository;
public List<Product> findByDataType(){
List<Product> productList = productRepository.findByDataType();
return productList;
}
};
public class CommunicatePython {
public void createHttpRequestAndSend(String query){
//필요한 객체 생성
RestTemplate restTemplate = new RestTemplate();
//body 생성
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("query", query);
//header 생성
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// header, body 합치기
HttpEntity<MultiValueMap<String,String>> entity = new HttpEntity<>(params, headers);
// POST 요청 보내고, 응답값을 JSONObject로 받기
JSONObject jsonObject = new JSONObject(restTemplate.postForObject("http://python서버 ip:포트번호/get_data", entity, String.class));
// Json 파싱
String result = jsonObject.getString("check");
return result;
}
};
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByDataType(String data_type);
};
機能が実現しました.
提出する
「開発」に移動
git checkout develop
merge
git merge features/request_to_python_server_with_http-ChaYoungHo
マージ完了
📋の最後の部分
2台のサーバをテスト中に多くのエラーが発生しました.経験した誤りは以下の通りである.
🧷Reference
Reference
この問題について(他のサーバへのリクエスト機能の実装), 我々は、より多くの情報をここで見つけました https://velog.io/@jkijki12/Spring-Request-기능-구현テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol