Skip to content

Commit 0d3d286

Browse files
authored
Merge pull request #1 from Meggi9/developer
Developer
2 parents 5a6ac07 + f321239 commit 0d3d286

File tree

18 files changed

+567
-17
lines changed

18 files changed

+567
-17
lines changed

Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM openjdk:17
2+
ADD target/GeocodingService-0.0.1-SNAPSHOT.jar GeocodingApp.jar
3+
ENTRYPOINT ["java", "-jar", "GeocodingApp.jar"]

README.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Web-сервис прямого и обратного геокодирования "GeocodingService"
2+
3+
#### Небходимые ПО
4+
* Docker
5+
* Postman
6+
* IntelliJ IDEA (в случае необходимости)
7+
8+
#### Используемые технологии
9+
* Java
10+
* Spring Boot
11+
* Maven
12+
* Redis (для кэширования)
13+
14+
#### Интеграция внешнего API: электронный справочник карт "2GIS" (Geocoder API): ````https://docs.2gis.com/ru/api/search/geocoder/overview````
15+
16+
#### Инструкция по запуску приложения
17+
1. git clone https://github.com/Meggi9/GeocodingService.git
18+
2. В директории проекта выполнить следующие команды:
19+
20+
* Сборка проекта maven: ````./mvnw package````
21+
22+
* Запуск приложения (в случае необходимости): ````java -jar target/GeocodingService-0.0.1-SNAPSHOT.jar````
23+
24+
2. Создание образа Docker: ````docker build -t geocoding-service-docker:0.1.0 .````
25+
5. Запуск контейнера Docker: ````docker run -p 8080:8080 geocoding-service-docker:0.1.0 .````
26+
27+
#### Инструкция по работе с приложением
28+
1. Для выполнения прямого геокодирования, следует выполнить следующий GET запрос:
29+
30+
````localhost:8080/api/geocoder````
31+
32+
При этом в тело запроса передать адрес в формате JSON:
33+
```json
34+
{
35+
"address": "Адрес"
36+
}
37+
````
38+
39+
2. Для выполнения обратного геокодирования, следует выполнить следующий GET запрос:
40+
41+
````localhost:8080/api/geocoder````
42+
43+
При этом в тело запроса передать координаты в формате JSON:
44+
```json
45+
{
46+
"lat": Значение широты,
47+
"lon": Значение долготы
48+
}
49+
````
50+
### Результаты работы приложения
51+
52+
1. Прямое геокодирование:
53+
54+
![image](https://user-images.githubusercontent.com/75883965/207918674-5923c1c5-c828-43e4-8162-2441e82966b3.png)
55+
56+
#### Полученный ответ (Response):
57+
58+
```json
59+
{
60+
"result": {
61+
"items": [
62+
{
63+
"building_name": "Воронежский государственный технический университет (ВГТУ)",
64+
"full_name": "Воронеж, Воронежский государственный технический университет (ВГТУ)",
65+
"purpose_name": "ВУЗ",
66+
"name": "Воронежский государственный технический университет (ВГТУ)",
67+
"address_name": "20-летия Октября, 84",
68+
"id": "4363497794194056",
69+
"type": "building",
70+
"point": {
71+
"lat": 51.652127,
72+
"lon": 39.192714
73+
}
74+
}
75+
],
76+
"total": "1"
77+
}
78+
}
79+
````
80+
81+
2. Обратное геокодирование:
82+
83+
![image](https://user-images.githubusercontent.com/75883965/207918880-24784c91-8b7f-46e7-bcf8-af60e1ae02cc.png)
84+
85+
#### Полученный ответ (Response):
86+
87+
```json
88+
{
89+
"result": {
90+
"items": [
91+
{
92+
"building_name": "Воронежский государственный технический университет (ВГТУ)",
93+
"full_name": "Воронеж, Воронежский государственный технический университет (ВГТУ)",
94+
"purpose_name": "ВУЗ",
95+
"name": "Воронежский государственный технический университет (ВГТУ)",
96+
"address_name": "20-летия Октября, 84",
97+
"id": "4363497794194056",
98+
"type": "building",
99+
"point": {
100+
"lat": 51.652127,
101+
"lon": 39.192714
102+
}
103+
},
104+
{
105+
"full_name": "Воронеж, Ленинский",
106+
"subtype": "district",
107+
"name": "Ленинский",
108+
"id": "4363472024371202",
109+
"type": "adm_div",
110+
"point": {
111+
"lat": 51.640025,
112+
"lon": 39.194786
113+
}
114+
},
115+
{
116+
"full_name": "Воронеж",
117+
"subtype": "city",
118+
"name": "Воронеж",
119+
"id": "4363484909273106",
120+
"type": "adm_div",
121+
"point": {
122+
"lat": 51.660548,
123+
"lon": 39.199775
124+
}
125+
},
126+
{
127+
"full_name": "Воронеж городской округ",
128+
"subtype": "district_area",
129+
"name": "Воронеж городской округ",
130+
"id": "70030076118167065",
131+
"type": "adm_div",
132+
"point": {
133+
"lat": 51.61521,
134+
"lon": 39.193904
135+
}
136+
},
137+
{
138+
"full_name": "Воронежская область",
139+
"subtype": "region",
140+
"name": "Воронежская область",
141+
"id": "1267655302447150",
142+
"type": "adm_div",
143+
"point": {
144+
"lat": 51.134329,
145+
"lon": 40.022274
146+
}
147+
}
148+
],
149+
"total": "5"
150+
}
151+
}
152+
````
153+
3. Реализация кэширования (Redis): _при повторном выполнении одинакового запроса время ответа значительно сокращается:_
154+
155+
* Первичное выполнение запроса:
156+
![Снимок экрана 2022-12-15 195352](https://user-images.githubusercontent.com/75883965/207921080-b3392251-5fc5-4e6e-9b26-1acc8e885840.png)
157+
158+
* Повторное выполнение запроса:
159+
![Снимок экрана 2022-12-15 195504](https://user-images.githubusercontent.com/75883965/207921134-8bc17a18-456e-459f-9438-25daa8451fc9.png)
160+

docker-compose.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: '3'
2+
3+
services:
4+
redis:
5+
container_name: 'redis'
6+
image: 'redis:latest'
7+
ports:
8+
- '6379:6379'
9+
app:
10+
container_name: 'geocoding-app'
11+
build: ./
12+
ports:
13+
- '8080:8080'
14+
links:
15+
- redis

pom.xml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
<relativePath/> <!-- lookup parent from repository -->
1010
</parent>
1111
<groupId>com.magatella</groupId>
12-
<artifactId>GeocogingService</artifactId>
12+
<artifactId>GeocodingService</artifactId>
1313
<version>0.0.1-SNAPSHOT</version>
14-
<name>GeocogingService</name>
15-
<description>GeocogingService</description>
14+
<name>GeocodingService</name>
15+
<description>GeocodingService</description>
1616
<properties>
1717
<java.version>17</java.version>
1818
</properties>
@@ -27,6 +27,18 @@
2727
<artifactId>spring-boot-starter-test</artifactId>
2828
<scope>test</scope>
2929
</dependency>
30+
31+
<dependency>
32+
<groupId>org.projectlombok</groupId>
33+
<artifactId>lombok</artifactId>
34+
<version>1.18.24</version>
35+
</dependency>
36+
37+
<dependency>
38+
<groupId>org.springframework.boot</groupId>
39+
<artifactId>spring-boot-starter-data-redis</artifactId>
40+
<version>2.7.0</version>
41+
</dependency>
3042
</dependencies>
3143

3244
<build>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.magatella.geocodingservice;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.cache.annotation.EnableCaching;
6+
7+
@SpringBootApplication
8+
@EnableCaching
9+
public class GeocodingServiceApplication {
10+
11+
public static void main(String[] args) {
12+
SpringApplication.run(GeocodingServiceApplication.class, args);
13+
}
14+
15+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.magatella.geocodingservice.config.cache;
2+
3+
import org.springframework.cache.Cache;
4+
import org.springframework.cache.CacheManager;
5+
import org.springframework.cache.annotation.CachingConfigurerSupport;
6+
import org.springframework.cache.annotation.EnableCaching;
7+
import org.springframework.cache.concurrent.ConcurrentMapCache;
8+
import org.springframework.cache.interceptor.KeyGenerator;
9+
import org.springframework.cache.support.SimpleCacheManager;
10+
import org.springframework.context.annotation.Bean;
11+
import org.springframework.context.annotation.Configuration;
12+
13+
import java.util.Arrays;
14+
15+
@EnableCaching
16+
@Configuration
17+
public class ApplicationConfig extends CachingConfigurerSupport {
18+
19+
@Bean
20+
public CacheManager cacheManager() {
21+
SimpleCacheManager cacheManager = new SimpleCacheManager();
22+
Cache requestCache = new ConcurrentMapCache("reqGeocod");
23+
cacheManager.setCaches(Arrays.asList(requestCache));
24+
return cacheManager;
25+
}
26+
27+
@Bean("customKeyGenerator")
28+
public KeyGenerator keyGenerator() {
29+
return new CustomKeyGenerator();
30+
}
31+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.magatella.geocodingservice.config.cache;
2+
3+
import org.springframework.cache.interceptor.KeyGenerator;
4+
import org.springframework.util.StringUtils;
5+
6+
import java.lang.reflect.Method;
7+
8+
public class CustomKeyGenerator implements KeyGenerator {
9+
@Override
10+
public Object generate(Object target, Method method, Object... params) {
11+
return target.getClass().getSimpleName() + "_"
12+
+ method.getName() + "_"
13+
+ StringUtils.arrayToDelimitedString(params, "_");
14+
}
15+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.magatella.geocodingservice.controller;
2+
3+
4+
import com.magatella.geocodingservice.entity.request.RequestDTO;
5+
import com.magatella.geocodingservice.entity.response.ResponseDTO;
6+
import com.magatella.geocodingservice.service.TwoGisGeocoderService;
7+
import org.springframework.cache.annotation.Cacheable;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.RequestBody;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RequestMethod;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
@RestController
15+
@RequestMapping(path = "/api")
16+
public class GeocoderController {
17+
18+
private final TwoGisGeocoderService geocoderService;
19+
20+
public GeocoderController(TwoGisGeocoderService geocoderService) {
21+
this.geocoderService = geocoderService;
22+
}
23+
24+
@Cacheable(value = "reqGeocod", keyGenerator = "customKeyGenerator")
25+
@RequestMapping(method = RequestMethod.GET, path = "/geocoder")
26+
public ResponseEntity<ResponseDTO> geo(@RequestBody RequestDTO requestDTO) {
27+
return geocoderService.checkTypeGeocoding(requestDTO);
28+
}
29+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.magatella.geocodingservice.entity.request;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class RequestDTO {
7+
private String address;
8+
9+
private String lat;
10+
11+
private String lon;
12+
13+
14+
}

0 commit comments

Comments
 (0)