From 648eb8a16dd1e6321d37eee88c306b91a865330e Mon Sep 17 00:00:00 2001 From: YH0223 <133633043+YH0223@users.noreply.github.com> Date: Sat, 7 Feb 2026 01:06:19 +0900 Subject: [PATCH 1/6] #10-NER-Python_module_added --- .../controller/AiAnalysisController.java | 22 ++++++++++++ .../demo/domain/nerfilter/dto/AiResponse.java | 32 +++++++++++++++++ .../demo/domain/nerfilter/dto/NerEntity.java | 9 +++++ .../domain/nerfilter/dto/TextRequest.java | 18 ++++++++++ .../nerfilter/service/AiAnalysisService.java | 35 +++++++++++++++++++ 5 files changed, 116 insertions(+) create mode 100644 src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java create mode 100644 src/main/java/com/example/demo/domain/nerfilter/dto/AiResponse.java create mode 100644 src/main/java/com/example/demo/domain/nerfilter/dto/NerEntity.java create mode 100644 src/main/java/com/example/demo/domain/nerfilter/dto/TextRequest.java create mode 100644 src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java diff --git a/src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java b/src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java new file mode 100644 index 0000000..2c7f8c8 --- /dev/null +++ b/src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java @@ -0,0 +1,22 @@ +package com.example.demo.domain.nerfilter.controller; + +import com.example.demo.domain.nerfilter.dto.AiResponse; +import com.example.demo.domain.nerfilter.dto.TextRequest; +import com.example.demo.domain.nerfilter.service.AiAnalysisService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController("/filter") +@RequiredArgsConstructor +public class AiAnalysisController { + + private final AiAnalysisService aiAnalysisService; + + @PostMapping("/check") + public AiResponse checkText(@RequestBody TextRequest request) { + // request.text()와 request.fix_spelling()이 포함된 객체가 그대로 서비스로 전달됨 + return aiAnalysisService.getAnalysis(request); + } +} diff --git a/src/main/java/com/example/demo/domain/nerfilter/dto/AiResponse.java b/src/main/java/com/example/demo/domain/nerfilter/dto/AiResponse.java new file mode 100644 index 0000000..626989e --- /dev/null +++ b/src/main/java/com/example/demo/domain/nerfilter/dto/AiResponse.java @@ -0,0 +1,32 @@ +package com.example.demo.domain.nerfilter.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; +import java.util.Map; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class AiResponse { + + @JsonProperty("original_text") + private String originalText; + + @JsonProperty("corrected_text") + private String correctedText; + + @JsonProperty("filtered_text") + private String filteredText; + + @JsonProperty("detected_entities") + private List> detectedEntities; // ✅ Object로 변경 + + @JsonProperty("spelling_errors") + private List> spellingErrors; // ✅ Object로 변경 +} diff --git a/src/main/java/com/example/demo/domain/nerfilter/dto/NerEntity.java b/src/main/java/com/example/demo/domain/nerfilter/dto/NerEntity.java new file mode 100644 index 0000000..4bebb0e --- /dev/null +++ b/src/main/java/com/example/demo/domain/nerfilter/dto/NerEntity.java @@ -0,0 +1,9 @@ +package com.example.demo.domain.nerfilter.dto; + +public record NerEntity( + String entity, + double score, + String word, + int start, + int end +) {} diff --git a/src/main/java/com/example/demo/domain/nerfilter/dto/TextRequest.java b/src/main/java/com/example/demo/domain/nerfilter/dto/TextRequest.java new file mode 100644 index 0000000..2a2c784 --- /dev/null +++ b/src/main/java/com/example/demo/domain/nerfilter/dto/TextRequest.java @@ -0,0 +1,18 @@ +package com.example.demo.domain.nerfilter.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class TextRequest { + + @JsonProperty("text") + private String text; + + @JsonProperty("fix_spelling") + private boolean fixSpelling = true; // 자바 관례대로 camelCase를 쓰고 JSON 이름만 지정 +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java b/src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java new file mode 100644 index 0000000..c9c588b --- /dev/null +++ b/src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java @@ -0,0 +1,35 @@ +package com.example.demo.domain.nerfilter.service; + +import com.example.demo.domain.nerfilter.dto.AiResponse; +import com.example.demo.domain.nerfilter.dto.TextRequest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClient; + +import org.springframework.http.MediaType; +import org.springframework.web.client.RestTemplate; + +@Service +public class AiAnalysisService { + + private final RestTemplate restTemplate; + private final String baseUrl = "http://13.209.148.142:80"; + + public AiAnalysisService() { + this.restTemplate = new RestTemplate(); + } + + public AiResponse getAnalysis(TextRequest text) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity request = new HttpEntity<>(text, headers); + + return restTemplate.postForObject( + baseUrl + "/filter", + request, + AiResponse.class + ); + } +} \ No newline at end of file From def9a97aef7476ac6c76a52bd11dd70f9f91c9dd Mon Sep 17 00:00:00 2001 From: ygcho Date: Sat, 7 Feb 2026 01:22:32 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=AC=ED=94=84?= =?UTF-8?q?=ED=8A=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gemini/exception/GeminiErrorCode.java | 6 +++++ .../domain/gemini/service/GeminiService.java | 27 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/demo/domain/gemini/exception/GeminiErrorCode.java b/src/main/java/com/example/demo/domain/gemini/exception/GeminiErrorCode.java index 295c3e0..c1313d0 100644 --- a/src/main/java/com/example/demo/domain/gemini/exception/GeminiErrorCode.java +++ b/src/main/java/com/example/demo/domain/gemini/exception/GeminiErrorCode.java @@ -47,6 +47,12 @@ public enum GeminiErrorCode implements BaseCode { HttpStatus.BAD_GATEWAY, "GEMINI-007", "GEMINI 응답에 아무 내용이 없습니다." + ), + + GEMINI_INVALID_INPUT( + HttpStatus.BAD_REQUEST, + "GEMINI-008", + "의미있는 고민을 입력해주세요." ); private final HttpStatus httpStatus; diff --git a/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java b/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java index b1c66b7..ce56e1c 100644 --- a/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java +++ b/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java @@ -36,10 +36,17 @@ public Map askGemini(String userContent) { String url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=" + cleanKey; - String systemPrompt = "유저의 고민을 듣고 다정하게 위로해줘." + - "너무 ai 같지 않게 사람답게 말하고, 유저를 절대 비난해서는 안돼." + - "무조건적인 공감과 지지를 보내줘. 핵심 키워드 3개 정도를 욕설 제외하고 뽑아줘. 갯수에 제한 받기 보다는, 정말 중요하다 생각되는 키워드를 뽑아." - + "반드시 JSON 형식으로만 대답해. 형식: {\"keyword\": [\"단어1\", \"단어2\", \"단어3\"], \"answer\": \"내용\"}"; + String systemPrompt = "너는 유저의 고민을 듣고 위로해주는 상담사야. " + + "먼저 유저의 입력이 위로가 필요한 상황인지 판단해. " + + "거부해야 할 입력: 숫자만 나열, 명백한 테스트 메시지(예: 'test', '테스트', '123'), 봇/스팸 같은 입력, 의미없는 단어 무한 반복. " + + "위로해줘야 할 입력: 고민/감정 표현, 한글 자음모음을 막 친 것(빡치거나 힘들어서 그럴 수 있음), 욕설이나 분노 표현, 짧은 한숨이나 감정 표현. " + + "만약 위로가 필요한 상황이라면: 다정하게 위로해주고, 너무 AI 같지 않게 사람답게 말해. " + + "유저를 절대 비난하지 말고, 무조건적인 공감과 지지를 보내줘. " + + "키보드를 막 친 것 같으면 '많이 힘드셨나봐요' 같은 공감을 표현해줘. " + + "핵심 키워드를 욕설 제외하고 3개 정도 뽑아줘. 감정 키워드도 괜찮아. 갯수에 제한받기보다는 정말 중요한 키워드만 뽑아. " + + "반드시 JSON 형식으로만 대답해. " + + "위로할 때: {\"isValid\": true, \"keyword\": [\"단어1\", \"단어2\"], \"answer\": \"위로 내용\"} " + + "거부할 때: {\"isValid\": false, \"keyword\": [], \"answer\": \"\"}"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); @@ -59,6 +66,13 @@ public Map askGemini(String userContent) { String cleanedJson = rawContent.replaceAll("(?s)```json|```", "").trim(); Map result = objectMapper.readValue(cleanedJson, Map.class); + // 무의미한 입력인지 확인 + Object isValidObj = result.get("isValid"); + boolean isValid = isValidObj instanceof Boolean ? (Boolean) isValidObj : true; + if (!isValid) { + throw new CustomException(GeminiErrorCode.GEMINI_INVALID_INPUT); + } + Object keywordObj = result.get("keyword"); if (keywordObj instanceof List) { List keywords = (List) keywordObj; @@ -72,11 +86,16 @@ public Map askGemini(String userContent) { } } + // isValid 필드 제거 후 반환 + result.remove("isValid"); return result; } catch (JsonProcessingException e) { throw new CustomException(GeminiErrorCode.GEMINI_PARSE_ERROR); } + } catch (CustomException e) { + // CustomException은 그대로 던지기 + throw e; } catch (HttpClientErrorException.NotFound e) { System.err.println("### 404 에러 상세: " + e.getResponseBodyAsString()); throw new CustomException(GeminiErrorCode.GEMINI_API_ERROR); From 920d9e8057517e83a598d572451c7be33d17b8df Mon Sep 17 00:00:00 2001 From: baseballclub Date: Sat, 7 Feb 2026 01:36:08 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[Feat]=20=EC=8A=A4=EC=BC=80=EC=A4=84?= =?UTF-8?q?=EB=9F=AC=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/demo/VoidApplication.java | 2 ++ .../ranking/controller/RankingController.java | 2 +- .../ranking/service/RankingService.java | 31 +++++++++++++------ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/example/demo/VoidApplication.java b/src/main/java/com/example/demo/VoidApplication.java index c8a106b..12c2662 100644 --- a/src/main/java/com/example/demo/VoidApplication.java +++ b/src/main/java/com/example/demo/VoidApplication.java @@ -2,8 +2,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication +@EnableScheduling public class VoidApplication { public static void main(String[] args) { diff --git a/src/main/java/com/example/demo/domain/ranking/controller/RankingController.java b/src/main/java/com/example/demo/domain/ranking/controller/RankingController.java index 003519e..5fcd505 100644 --- a/src/main/java/com/example/demo/domain/ranking/controller/RankingController.java +++ b/src/main/java/com/example/demo/domain/ranking/controller/RankingController.java @@ -28,7 +28,7 @@ public class RankingController { ) @GetMapping("/top3") public ApiResponse>> getTop3() { - List> result = rankingService.getTop3WithPercentage(); + List> result = rankingService.getTop3(); return ApiResponse.onSuccess(result, SuccessCode.OK); } } \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/ranking/service/RankingService.java b/src/main/java/com/example/demo/domain/ranking/service/RankingService.java index 7600649..d8e594f 100644 --- a/src/main/java/com/example/demo/domain/ranking/service/RankingService.java +++ b/src/main/java/com/example/demo/domain/ranking/service/RankingService.java @@ -3,14 +3,12 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ZSetOperations; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @Service @@ -18,6 +16,8 @@ public class RankingService { private final StringRedisTemplate redisTemplate; + // 20분마다 갱신된 결과를 저장할 메모리 캐시 + private List> cachedTop3Ranking = new ArrayList<>(); // 시간별 redis key 생성 private String getRankingkey() { @@ -35,15 +35,27 @@ public void incrementKeywordCount(String keyword) { redisTemplate.opsForZSet().incrementScore(key, keyword, 1); } - public List> getTop3WithPercentage() { - String key = getRankingkey(); + // 20분마다 무거운 계산(전체 합계 및 퍼센트)을 미리 수행 + @Scheduled(fixedRate = 1200000) // 20분(ms 단위) + public void updateRankingCache() { + System.out.println("### [스케줄러] 20분 주기 랭킹 캐시 갱신 시작"); + this.cachedTop3Ranking = calculateTop3WithPercentage(); + } + + public List> getTop3() { + if (cachedTop3Ranking.isEmpty()) { + return calculateTop3WithPercentage(); // 캐시가 비어있을 때만 직접 계산 + } + return cachedTop3Ranking; + } + private List> calculateTop3WithPercentage() { + String key = getRankingkey(); Set> top3WithScores = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 2); if (top3WithScores == null || top3WithScores.isEmpty()) return List.of(); - // 현재 시간대의 전체 소각 횟수 합 Double totalScore = 0.0; Set> allItems = redisTemplate.opsForZSet().rangeWithScores(key, 0, -1); @@ -58,13 +70,12 @@ public List> getTop3WithPercentage() { return top3WithScores.stream().map(tuple -> { Map map = new LinkedHashMap<>(); double score = tuple.getScore() != null ? tuple.getScore() : 0.0; - double percentage = (score / finalTotalScore) * 100; + double percentage = finalTotalScore > 0 ? (score / finalTotalScore) * 100 : 0; map.put("keyword", tuple.getValue()); map.put("percentage", Math.round(percentage) + "%"); return map; }).collect(Collectors.toList()); } + } - -} From bc1cef28b66f143acf86ce328d22bebd9c90f180 Mon Sep 17 00:00:00 2001 From: baseballclub Date: Sat, 7 Feb 2026 02:15:26 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[Feat]=20=EA=B0=9C=EC=9D=B8=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gemini/controller/GeminiController.java | 23 +++++++++---------- .../domain/gemini/service/GeminiService.java | 16 ++++++++++++- .../controller/AiAnalysisController.java | 22 ------------------ 3 files changed, 26 insertions(+), 35 deletions(-) delete mode 100644 src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java diff --git a/src/main/java/com/example/demo/domain/gemini/controller/GeminiController.java b/src/main/java/com/example/demo/domain/gemini/controller/GeminiController.java index b5c8287..21b788a 100644 --- a/src/main/java/com/example/demo/domain/gemini/controller/GeminiController.java +++ b/src/main/java/com/example/demo/domain/gemini/controller/GeminiController.java @@ -1,6 +1,8 @@ package com.example.demo.domain.gemini.controller; import com.example.demo.domain.gemini.service.GeminiService; +import com.example.demo.domain.nerfilter.dto.AiResponse; +import com.example.demo.domain.nerfilter.dto.TextRequest; import com.example.demo.shared.exception.CustomException; import com.example.demo.shared.response.ApiResponse; import com.example.demo.shared.response.ErrorCode; @@ -24,32 +26,29 @@ public class GeminiController { @Operation( summary = "감정 배출 및 키워드 추출", - description = "유저의 감정(content)을 보내면 gemini가 답변과 핵심 키워드를 반환합니다." + description = "유저의 감정(text)을 보내면 gemini가 답변과 핵심 키워드를 반환합니다." ) @io.swagger.v3.oas.annotations.parameters.RequestBody( description = "상담할 고민 내용", required = true, content = @Content( mediaType = "application/json", - schema = @Schema(example = "{\"content\": \"오늘 해커톤 너무 힘들다.\"}"), + schema = @Schema(example = "{\"text\": \"오늘 해커톤 너무 힘들다.\"}"), examples = @ExampleObject( name = "고민 상담 예시", - value = "{\"content\": \"해커톤 프로젝트가 생각보다 어려워서 속상해...\"}" + value = "{\"text\": \"해커톤 프로젝트가 생각보다 어려워서 속상해...\"}" ) ) ) @PostMapping("/ask") - public ApiResponse> ask(@RequestBody Map request) { - String userContent = request.get("content"); - - if (userContent == null || userContent.isBlank()) { - return ApiResponse.onSuccess( - Map.of("answer", "내용을 입력해 주세요!", "keyword", "입력 필요"), - SuccessCode.OK - ); + public ApiResponse> ask(@RequestBody TextRequest textRequest) { + String userText = textRequest.getText(); + + if (userText == null || userText.isBlank()) { + throw new CustomException(ErrorCode.INVALID_REQUEST); } - Map result = geminiService.askGemini(userContent); + Map result = geminiService.askGemini(userText); return ApiResponse.onSuccess(result, SuccessCode.OK); } diff --git a/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java b/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java index ce56e1c..4ccd4c1 100644 --- a/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java +++ b/src/main/java/com/example/demo/domain/gemini/service/GeminiService.java @@ -3,6 +3,9 @@ import com.example.demo.domain.gemini.dto.GeminiRequest; import com.example.demo.domain.gemini.dto.GeminiResponse; import com.example.demo.domain.gemini.exception.GeminiErrorCode; +import com.example.demo.domain.nerfilter.dto.AiResponse; +import com.example.demo.domain.nerfilter.dto.TextRequest; +import com.example.demo.domain.nerfilter.service.AiAnalysisService; import com.example.demo.domain.ranking.service.RankingService; import com.example.demo.shared.exception.CustomException; import com.fasterxml.jackson.core.JsonProcessingException; @@ -31,7 +34,18 @@ public class GeminiService { private final ObjectMapper objectMapper; private final RankingService rankingService; + private final AiAnalysisService aiAnalysisService; + public Map askGemini(String userContent) { + TextRequest textRequest = new TextRequest(userContent, true); + AiResponse aiResponse = aiAnalysisService.getAnalysis(textRequest); + + String filteredContent = aiResponse.getFilteredText(); + if (filteredContent == null || filteredContent.isBlank()) { + throw new CustomException(GeminiErrorCode.GEMINI_NO_CONTENT); + } + + String cleanKey = apiKey.trim(); String url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=" + cleanKey; @@ -51,7 +65,7 @@ public Map askGemini(String userContent) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); - GeminiRequest request = GeminiRequest.of(systemPrompt, userContent); + GeminiRequest request = GeminiRequest.of(systemPrompt, filteredContent); HttpEntity entity = new HttpEntity<>(request, headers); try { diff --git a/src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java b/src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java deleted file mode 100644 index 2c7f8c8..0000000 --- a/src/main/java/com/example/demo/domain/nerfilter/controller/AiAnalysisController.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.example.demo.domain.nerfilter.controller; - -import com.example.demo.domain.nerfilter.dto.AiResponse; -import com.example.demo.domain.nerfilter.dto.TextRequest; -import com.example.demo.domain.nerfilter.service.AiAnalysisService; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -@RestController("/filter") -@RequiredArgsConstructor -public class AiAnalysisController { - - private final AiAnalysisService aiAnalysisService; - - @PostMapping("/check") - public AiResponse checkText(@RequestBody TextRequest request) { - // request.text()와 request.fix_spelling()이 포함된 객체가 그대로 서비스로 전달됨 - return aiAnalysisService.getAnalysis(request); - } -} From 551d208d2c72ae6b906c30a06d4f6a58b11f2af5 Mon Sep 17 00:00:00 2001 From: YH0223 <133633043+YH0223@users.noreply.github.com> Date: Sat, 7 Feb 2026 03:00:31 +0900 Subject: [PATCH 5/6] CORS_CONFIG --- .gitignore | 2 +- .../example/demo/core/config/WebConfig.java | 20 +++++++++++++++++++ .../nerfilter/service/AiAnalysisService.java | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/demo/core/config/WebConfig.java diff --git a/.gitignore b/.gitignore index c2065bc..f833506 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ - +.env ### STS ### .apt_generated .classpath diff --git a/src/main/java/com/example/demo/core/config/WebConfig.java b/src/main/java/com/example/demo/core/config/WebConfig.java new file mode 100644 index 0000000..aa1005a --- /dev/null +++ b/src/main/java/com/example/demo/core/config/WebConfig.java @@ -0,0 +1,20 @@ +package com.example.demo.core.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") // 모든 경로에 대해 + .allowedOrigins( "https://jyhdevstore.store","https://void-fe-nine.vercel.app") // 프론트엔드, NER + .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS") + .allowedHeaders("*") + .allowCredentials(true) + .maxAge(3600); + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java b/src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java index c9c588b..2cac95b 100644 --- a/src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java +++ b/src/main/java/com/example/demo/domain/nerfilter/service/AiAnalysisService.java @@ -14,7 +14,7 @@ public class AiAnalysisService { private final RestTemplate restTemplate; - private final String baseUrl = "http://13.209.148.142:80"; + private final String baseUrl = "https://jyhdevstore.store"; public AiAnalysisService() { this.restTemplate = new RestTemplate(); From 1668710a68cf7ac6bad8018077b7d332c47c6b7c Mon Sep 17 00:00:00 2001 From: YH0223 <133633043+YH0223@users.noreply.github.com> Date: Sat, 7 Feb 2026 03:02:40 +0900 Subject: [PATCH 6/6] CORS_CONFIG --- src/main/java/com/example/demo/core/config/WebConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/demo/core/config/WebConfig.java b/src/main/java/com/example/demo/core/config/WebConfig.java index aa1005a..1c6eb59 100644 --- a/src/main/java/com/example/demo/core/config/WebConfig.java +++ b/src/main/java/com/example/demo/core/config/WebConfig.java @@ -10,7 +10,7 @@ public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 모든 경로에 대해 - .allowedOrigins( "https://jyhdevstore.store","https://void-fe-nine.vercel.app") // 프론트엔드, NER + .allowedOrigins( "https://jyhdevstore.store","https://void-fe-nine.vercel.app","https://voidvoid.store/") // 프론트엔드, NER, BE .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS") .allowedHeaders("*") .allowCredentials(true)