26 Mart 2018 Pazartesi

Java ve Spring ile JSON-RPC Sunucu

Python, C++, Görüntü işleme, Derin öğrenme vs. derken, yazılım alanında Türkçe kaynak oluşmasına katkıda bulunma adına bir projemizde aktif kullandığımız Java ile JSON-RPC kullanımına dair bir blog yazısı hazırladım. Bu yazı kapsamında size, Spring ve jsonrpc4j kullanarak "Java ile nasıl ve en kolay(hızlı) JSON-RPC sunucu uygulaması geliştirebiliriz" sorusunun cevabını vermeye çalışacağım. Ve her ne kadar bu yazının konusu Java diye belirlediysek de, JSON-RPC sunucumuza istek gönderen uygulamamızı yine Python ile geliştireceğiz.


İlk olarak https://start.spring.io/ adresinden Java Spring Boot ve Maven ile projemizi oluşturuyoruz. Eclipse ile de File-> New -> "Spring Starter Project" ile projemizi oluşturabiliriz. Maven bağımlıklık yönetim aracının, jsonrpc4j için gerekli yüklemeleri yapması için pom.xml dosyasına aşağıdaki bağımlılığı (dependency) 'i ekliyoruz.
 <!-- jsonrpc4j -->
 <dependency>
  <groupId>com.github.briandilley.jsonrpc4j</groupId>
  <artifactId>jsonrpc4j</artifactId>
  <version>1.5.2</version>
 </dependency>

Projemizde bir Service Interface tanımlıyoruz. Bizim örneğimizde, sunucumuz 2 fonksiyonu implement'e edecek. Bunlar iki sayıyı çarpan basit bir çarpma metodu ile bir String listesini verilen bir diğer String'e göre birleştirip tek bir String haline getiren basit bir fonksiyon olsun. ServiceApi isimli bir java dosyayı oluşturup, aşağıdaki gibi Service tanımlıyoruz.


Burada dikkat edeceğimiz nokta; @JsonRpcService("/utility") annotation

Daha sonra bu fonksiyonları implement edeceğimiz, ServiceApiImpl isimli bir dosya daha ekleyip, metodlarımızın içerisini dolduruyoruz.

Burada dikkat edeceğimiz nokta ise, @AutoJsonRpcServiceImpl  ile Service Interface'in implementasyonu için annotation eklemek. Artık bu sınıf JSON-RPC Servis olarak Spring tarafından yönetilecek.

Son olarak ise @Configuration sınıfımızda;
AutoJsonRpcServiceImplExporter  bean tanımlamalıyız.

import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ApplicationConfig {

    @Bean
    public static AutoJsonRpcServiceImplExporter autoJsonRpcServiceImplExporter() {
        AutoJsonRpcServiceImplExporter exp = new AutoJsonRpcServiceImplExporter();
        //in here you can provide custom HTTP status code providers etc. eg:
        //exp.setHttpStatusCodeProvider();
        //exp.setErrorResolver();
        return exp;
    }
}

JSON-RPC sunucumuz hazır, uygulamayı çalıştırdıktan sonra bir başka uygulama ile sunucuya bağlanıp tanımladığımız her iki metodu çağırabiliriz. Bunun için aşağıdaki python koduna göz atalım.

import json
import requests

from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

data = {}
data['jsonrpc'] = '2.0'
data['id'] = '1'
data['method'] = "multiplier"  // cagrilacak metod ismi

params={} 
params['a'] = 5
params['b'] = 7    
data['params'] = params  
json_data = json.dumps(data)


headers = {'Content-type': 'application/json', 'Accept': 'application/json'}

r = requests.post('http://localhost:8080/utility', data=json.dumps(data), verify=False, headers=headers)

answer = r.text

http://localhost:8080/utility adresine json_data post ediyoruz. json_data nın içeriğine bakacak olursanız, method = multiplier ve a=5, b=7 parametreleri ile ilgili metodu çağırıyoruz. İsteğimize dönen cevap;
stringJoin metodunu çağırmak için ilgili python kodu ve isteğimize dönen cevap ise aşağıdaki gibi olacaktır.
data = {}
data['jsonrpc'] = '2.0'
data['id'] = '1'
data['method'] = "stringJoin"

params={} 
params['str'] = ["Bilinmez","neleri","getirir","zaman"]
params['b'] = "," 
data['params'] = params  
json_data = json.dumps(data)

headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
r = requests.post('http://localhost:8080/utility', data=json.dumps(data), verify=False, headers=headers)

answer = r.text

Son olarak json formatında dönen cevabı kolayca Python dictionary 'e çevirip (decode edip) dönen cevabı şu şekilde çekebiliriz.
answer = json.loads(answer)
result = answer['result']

Bir yazının daha sonuna geldik, umarım ilgili kişilere bir faydamız dokunur. 
Her türlü görüş, öneri ve sorularınızı iletebilirsiniz...

Hiç yorum yok:

Yorum Gönder