Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#1) : Spring Batch 구현 #2

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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