Skip to content

Commit

Permalink
Merge pull request #2 from kusitms-28th-Meetup-E/feat/batch
Browse files Browse the repository at this point in the history
feat(#1) : Spring Batch 구현
  • Loading branch information
eojinny authored Nov 13, 2023
2 parents 6be239f + 3caedb3 commit 5bc15e2
Show file tree
Hide file tree
Showing 15 changed files with 462 additions and 1 deletion.
15 changes: 15 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ configurations {

repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}

ext {
Expand Down Expand Up @@ -69,6 +70,20 @@ dependencies {

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

// 형태소
implementation 'com.github.shin285:KOMORAN:3.3.4'

implementation 'org.json:json:20210307'
implementation 'com.googlecode.json-simple:json-simple:1.1'



implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0' // 사용 가능한 최신 버전으로 업데이트하세요

//spring batch
implementation 'org.springframework.boot:spring-boot-starter-batch'

implementation "org.springframework.boot:spring-boot-starter-quartz"

}

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/gwangjang/server/KeywordServiceApplication.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package gwangjang.server;

import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableBatchProcessing
public class KeywordServiceApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gwangjang.server.domain.morpheme.domain.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class Issue {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "issue_id")
private Long id;
private String issueTitle;
@ManyToOne
@JoinColumn(name = "topic_id")
private Topic topic;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package gwangjang.server.domain.morpheme.domain.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;


@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Morpheme {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "morpheme_id")
private Long id;

private String word;

private int count;

private int issueId;


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gwangjang.server.domain.morpheme.domain.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class Topic {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "topic_id")
private Long id;

private String topicTitle;


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package gwangjang.server.domain.morpheme.domain.repository;

import gwangjang.server.domain.morpheme.domain.entity.Morpheme;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MorphemeRepository extends JpaRepository<Morpheme,Long> {
Morpheme findByWordAndIssueId(String word, int issueId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gwangjang.server.domain.morpheme.domain.service;

import gwangjang.server.domain.morpheme.domain.entity.Morpheme;
import gwangjang.server.domain.morpheme.domain.repository.MorphemeRepository;
import gwangjang.server.global.annotation.DomainService;
import jakarta.transaction.Transactional;
import kr.co.shineware.nlp.komoran.model.Token;
import lombok.RequiredArgsConstructor;

import java.util.List;

@DomainService
@Transactional
@RequiredArgsConstructor
public class MorphemeService {
private final MorphemeRepository morphemeRepository;

@Transactional
public void saveOrUpdateWord(List<Token> tokens , int id) {
for (Token token : tokens) {
String word = token.getMorph();
System.out.println("save " + word);
Morpheme existingWord = morphemeRepository.findByWordAndIssueId(word,3);
if (existingWord != null) {
// 단어가 이미 존재하면 count를 업데이트
existingWord.setCount(existingWord.getCount() + 1);
System.out.println(existingWord.getWord());
morphemeRepository.save(existingWord);
} else {
// 단어가 존재하지 않으면 새로운 레코드를 생성
Morpheme newWord = new Morpheme();
newWord.setWord(word);
System.out.println("else save " +word);
newWord.setCount(1);
newWord.setIssueId(id);
morphemeRepository.save(newWord);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package gwangjang.server.domain.morpheme.domain.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import gwangjang.server.global.annotation.DomainService;
import jakarta.transaction.Transactional;
import kr.co.shineware.nlp.komoran.constant.DEFAULT_MODEL;
import kr.co.shineware.nlp.komoran.core.Komoran;
import kr.co.shineware.nlp.komoran.model.KomoranResult;
import kr.co.shineware.nlp.komoran.model.Token;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;


@DomainService
@Transactional
public class NewsAPIService {
@Value("${naver.client-id}")
private String NAVER_API_ID;

@Value("${naver.secret}")
private String NAVER_API_SECRET;
private final RestTemplate restTemplate;
ObjectMapper objectMapper = new ObjectMapper();



@Autowired
public NewsAPIService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}


public String naverAPI(String name) throws JsonProcessingException {

StringBuilder rslt = new StringBuilder();

for (int start = 1; start <= 1000; start += 100) {
URI uri = UriComponentsBuilder
.fromUriString("https://openapi.naver.com/")
.path("/v1/search/news.json")
.queryParam("query", name)
.queryParam("display", 100)
.queryParam("start", start)
.queryParam("sort", "sim")
.encode(StandardCharsets.UTF_8)
.build()
.toUri();

RequestEntity<Void> req = RequestEntity
.get(uri)
.header("X-Naver-Client-Id", NAVER_API_ID)
.header("X-Naver-Client-Secret", NAVER_API_SECRET)
.build();

ResponseEntity<String> result = restTemplate.exchange(req, String.class);
String json = result.getBody();
System.out.println(json);

try {
JSONParser parser = new JSONParser();
JSONObject jsonData = (JSONObject) parser.parse(json);
JSONArray items = (JSONArray) jsonData.get("items");

for (Object obj : items) {
JSONObject item = (JSONObject) obj;

String title = (String) item.get("title");
String description = (String) item.get("description");
rslt.append(title);
rslt.append(description);
}

} catch (Exception e) {
e.printStackTrace();
}
}

return rslt.toString();
}

public List<Token> analysis(String msg) {

Komoran komoran = new Komoran(DEFAULT_MODEL.FULL);
KomoranResult analyzeResultList = komoran.analyze(msg);

System.out.println(analyzeResultList.getPlainText());

List<Token> tokenList = analyzeResultList.getTokenList();

for (Token token : tokenList) {
System.out.format("%s\n", token.getMorph());
}
return tokenList;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package gwangjang.server.domain.morpheme.presentation;

import com.fasterxml.jackson.core.JsonProcessingException;
import gwangjang.server.domain.morpheme.domain.service.MorphemeService;
import gwangjang.server.domain.morpheme.domain.service.NewsAPIService;
import io.swagger.annotations.ApiOperation;
import kr.co.shineware.nlp.komoran.model.Token;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/keyword")
@RequiredArgsConstructor
public class MorphemeController {

private final NewsAPIService newsAPIService;
private final MorphemeService morphemeService;
@GetMapping("/analysis/{msg}")
public String analysis(@PathVariable String msg) throws JsonProcessingException {
String newsList1 = newsAPIService.naverAPI("주 69시간 근로시간 제도 개편");
String newsList2 = newsAPIService.naverAPI("이태원 참사");
String newsList3 = newsAPIService.naverAPI("국민연금 개혁");
List<Token> newsAnalysis1 =newsAPIService.analysis(newsList1);
List<Token> newsAnalysis2 =newsAPIService.analysis(newsList2);
List<Token> newsAnalysis3 =newsAPIService.analysis(newsList3);
morphemeService.saveOrUpdateWord(newsAnalysis1, 100 );
morphemeService.saveOrUpdateWord(newsAnalysis2, 200);
morphemeService.saveOrUpdateWord(newsAnalysis3, 300);
return "success";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package gwangjang.server.global.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(5000);
requestFactory.setReadTimeout(5000);

restTemplate.setRequestFactory(requestFactory);

return restTemplate;
}
}
Loading

0 comments on commit 5bc15e2

Please sign in to comment.