This commit is contained in:
lunaticbum 2024-10-04 14:53:37 +09:00
parent 62475fde46
commit 7df54a521c
13 changed files with 240 additions and 196 deletions

View File

@ -5,14 +5,17 @@ ENV WEATHER_KEY=default
ENV BOT_KEY=default ENV BOT_KEY=default
ENV DATASOURCE_URL=default ENV DATASOURCE_URL=default
ENV MONGODB_HOST=default ENV MONGODB_HOST=default
ENV MONGODB_NAME=default
ENV MRA_ADMIN=default
ENV MRA_PW=default
LABEL maintainer="lunaticbum <lunaticbum@gmail.com>" LABEL maintainer="lunaticbum <lunaticbum@gmail.com>"
LABEL version="0.0.4" LABEL version="0.0.4"
LABEL description="Spring Boot Jar Test" LABEL description="Spring Boot Jar Test"
ARG JAR_FILE=build/libs/lun-0.0.4-SNAPSHOT.jar ARG JAR_FILE=build/libs/lun-0.0.5-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar COPY ${JAR_FILE} app.jar
EXPOSE 8080 EXPOSE 443
EXPOSE 27012 EXPOSE 27012
EXPOSE 3307 EXPOSE 3307
ENTRYPOINT ["java","-Dtelegram.bot.key=${BOT_KEY}","-Dtelegram.my.id=${TG_MINE}","-Dtelegram.target.id=${TG_TARGET_ID}","-Dweather.api.key=${WEATHER_KEY}","-Dspring.datasource.url=${DATASOURCE_URL}" ,"-Dspring.data.mongodb.host=${MONGODB_HOST}" ,"-jar","app.jar"] ENTRYPOINT ["java","-Dtelegram.bot.key=${BOT_KEY}","-Dtelegram.my.id=${TG_MINE}","-Dtelegram.target.id=${TG_TARGET_ID}","-Dweather.api.key=${WEATHER_KEY}","-Dspring.datasource.url=${DATASOURCE_URL}" ,"-Dspring.data.mongodb.uri=${MONGODB_HOST}","-Dspring.data.mongodb.database=${MONGODB_NAME}","-Dspring.datasource.username=${MRA_ADMIN}","-Dspring.datasource.password=${MRA_PW}","-jar","app.jar"]
#ENTRYPOINT ["java","-jar","app.jar","-Dspring-boot.run.arguments=--telegram.bot.key=${BOT_KEY}, --telegram.my.id=${TG_MINE}, --telegram.target.id=${TG_TARGET_ID}, --weather.api.key=${WEATHER_KEY}"] #ENTRYPOINT ["java","-jar","app.jar","-Dspring-boot.run.arguments=--telegram.bot.key=${BOT_KEY}, --telegram.my.id=${TG_MINE}, --telegram.target.id=${TG_TARGET_ID}, --weather.api.key=${WEATHER_KEY}"]

View File

@ -6,7 +6,7 @@ plugins {
} }
group = "kr.lunaticbum.back" group = "kr.lunaticbum.back"
version = "0.0.4-SNAPSHOT" version = "0.0.5-SNAPSHOT"
java { java {
toolchain { toolchain {
@ -40,6 +40,8 @@ dependencies {
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
compileOnly("org.projectlombok:lombok") compileOnly("org.projectlombok:lombok")
runtimeOnly("org.mariadb.jdbc:mariadb-java-client") runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
annotationProcessor("org.projectlombok:lombok") annotationProcessor("org.projectlombok:lombok")

View File

@ -0,0 +1,124 @@
//package kr.lunaticbum.back.lun.configs
//
//import io.netty.channel.ChannelOption
//import io.netty.handler.timeout.ReadTimeoutHandler
//import io.netty.handler.timeout.WriteTimeoutHandler
//import jakarta.servlet.ServletContext
//import jakarta.servlet.ServletException
//import kr.lunaticbum.back.lun.utils.LogService
//import lombok.RequiredArgsConstructor
//import org.springframework.beans.factory.annotation.Autowired
//import org.springframework.beans.factory.annotation.Qualifier
//import org.springframework.context.annotation.Bean
//import org.springframework.http.client.reactive.ReactorClientHttpConnector
//import org.springframework.web.WebApplicationInitializer
//import org.springframework.web.context.ContextLoaderListener
//import org.springframework.web.context.support.AnnotationConfigWebApplicationContext
//import org.springframework.web.reactive.function.client.ClientRequest
//import org.springframework.web.reactive.function.client.ClientResponse
//import org.springframework.web.reactive.function.client.ExchangeFilterFunction
//import org.springframework.web.reactive.function.client.WebClient
//import org.springframework.web.servlet.DispatcherServlet
//import org.springframework.web.servlet.HandlerInterceptor
//import org.springframework.web.servlet.config.annotation.InterceptorRegistry
//import org.springframework.web.util.DefaultUriBuilderFactory
//import reactor.core.publisher.Mono
//import reactor.netty.Connection
//import reactor.netty.http.client.HttpClient
//import java.time.Duration
//import java.util.concurrent.TimeUnit
//import java.util.function.Consumer
//
//
//@RequiredArgsConstructor
//class WebConfig : WebApplicationInitializer {
//
// lateinit var logService : LogService
//
// var factory: DefaultUriBuilderFactory = DefaultUriBuilderFactory()
//
// var httpClient: HttpClient = HttpClient.create()
// .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) // 10초
//
//
// @Throws(ServletException::class)
// override fun onStartup(servletContext: ServletContext) {
// // Spring MVC 프로젝트 설정을 위해 작성하는 클래스의 객체를 생성한다.
// val servletAppContext = AnnotationConfigWebApplicationContext()
//// servletAppContext.register(ServletAppContext::class.java)
//
// // 요청 발생 시 요청을 처리하는 서블릿을 DispatcherServlet으로 설정해준다.
//// val dispatcherServlet = DispatcherServlet(servletAppContext)
//// val servlet = servletContext.addServlet("dispatcher", dispatcherServlet)
////
//// // 부가 설정
//// servlet.setLoadOnStartup(1)
//// servlet.addMapping("/")
//
// // Bean을 정의하는 클래스를 지정한다.
// val rootAppContext = AnnotationConfigWebApplicationContext()
// rootAppContext.register(RootAppContext::class.java)
//
// val listener = ContextLoaderListener(rootAppContext)
// servletContext.addListener(listener)
// }
//
//
//
//
// @Bean
// fun webClient(): WebClient {
// /**
// * 통신시 timeout 세팅
// * - connect, read, write 를 모두 5000ms
// */
//
// val httpClient = HttpClient.create()
// .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
// .responseTimeout(Duration.ofMillis(5000))
// .doOnConnected { conn: Connection ->
// conn.addHandlerLast(ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS))
// .addHandlerLast(WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS))
// }
//
// val webClient = WebClient.builder()
// .baseUrl("https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w")
// .clientConnector(ReactorClientHttpConnector(httpClient)) //생성한 HttpClient 연결
// //Request Header 로깅 필터
// .filter(
// ExchangeFilterFunction.ofRequestProcessor { clientRequest: ClientRequest ->
// logService.log(">>>>>>>>> REQUEST <<<<<<<<<<")
// logService.log("Request: ${clientRequest.method()} ${clientRequest.url()}")
// clientRequest.headers()
// .forEach { (name: String?, values: MutableList<String?>?) ->
// values.forEach(
// Consumer<String> { value: String? ->
// logService.log(
// "${name} : ${value}"
// )
// })
// }
// Mono.just<ClientRequest>(clientRequest)
// }
// ) //Response Header 로깅 필터
// .filter(
// ExchangeFilterFunction.ofResponseProcessor { clientResponse: ClientResponse ->
// logService.log(">>>>>>>>>> RESPONSE <<<<<<<<<<")
// clientResponse.headers().asHttpHeaders()
// .forEach { (name: String?, values: MutableList<String?>?) ->
// values.forEach(
// Consumer<String> { value: String? ->
// logService.log(
// "${name} ${value}"
// )
// })
// }
// Mono.just<ClientResponse>(clientResponse)
// }
// )
// .defaultHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8") //기본 헤더설정
// .build()
//
// return webClient
// }
//}

View File

@ -7,7 +7,6 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc
@Configuration @Configuration
@EnableWebMvc
class AppConfig { class AppConfig {
// @Bean // @Bean

View File

@ -7,7 +7,6 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc
@Configuration @Configuration
@EnableWebMvc
@ComponentScan(excludeFilters = [ComponentScan.Filter(type = FilterType.ANNOTATION, classes = arrayOf(Configuration::class))]) @ComponentScan(excludeFilters = [ComponentScan.Filter(type = FilterType.ANNOTATION, classes = arrayOf(Configuration::class))])
class AutoAppConfig { class AutoAppConfig {

View File

@ -1,30 +1,46 @@
package kr.lunaticbum.back.lun.configs package kr.lunaticbum.back.lun.configs
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.EnableWebMvc import org.springframework.http.CacheControl
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry import org.springframework.web.servlet.HandlerInterceptor
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry import org.springframework.web.servlet.config.annotation.*
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer import java.util.concurrent.TimeUnit
// Spring MVC 프로젝트에 관련된 설정을 하는 클래스 //// Spring MVC 프로젝트에 관련된 설정을 하는 클래스
@Configuration // Controller 어노테이션이 셋팅되어 있는 클래스를 Controller로 등록한다. //@Configuration // Controller 어노테이션이 셋팅되어 있는 클래스를 Controller로 등록한다.
@EnableWebMvc // 스캔할 패키지를 지정한다. ////@ComponentScan("kr.lunaticbum.back.lun.controllers")
@ComponentScan("kr.lunaticbum.back.lun.controllers") //internal class ServletAppContext : WebMvcConfigurer {
internal class ServletAppContext : WebMvcConfigurer { // // // Controller의 메서드가 반환하는 jsp의 이름 앞뒤에 경로와 확장자를 붙혀주도록 설정한다.
// Controller의 메서드가 반환하는 jsp의 이름 앞뒤에 경로와 확장자를 붙혀주도록 설정한다. //// override fun configureViewResolvers(registry: ViewResolverRegistry) {
override fun configureViewResolvers(registry: ViewResolverRegistry) { //// // TODO Auto-generated method stub
// TODO Auto-generated method stub //// super.configureViewResolvers(registry)
super.configureViewResolvers(registry) ////// registry.viewResolver { viewName, locale -> }
// registry.viewResolver { viewName, locale -> } ////// registry.jsp("/WEB-INF/views/", ".jsp")
// registry.jsp("/WEB-INF/views/", ".jsp") //// }
} ////
//// // 정적 파일의 경로를 매핑한다.
// 정적 파일의 경로를 매핑한다. // override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
override fun addResourceHandlers(registry: ResourceHandlerRegistry) { // // TODO Auto-generated method stub
// TODO Auto-generated method stub //// super.addResourceHandlers(registry)
super.addResourceHandlers(registry) // registry
registry.addResourceHandler("/**").addResourceLocations("/resources/") // .addResourceHandler("/")
} //// .addResourceHandler("/**")
} // .addResourceLocations("classpath:/META-INF/resources/")
// .addResourceLocations("classpath:/static/")
// .addResourceLocations("classpath:/templates/")
// .addResourceLocations("classpath:/templates/user/")
// .setCacheControl(CacheControl.maxAge(10,TimeUnit.SECONDS))
// super.addResourceHandlers(registry)
// }
//// @Autowired
//// @Qualifier(value = "authInterceptor")
//// private val authInterceptor: HandlerInterceptor? = null
////
//// override fun addInterceptors(registry: InterceptorRegistry) {
//// registry.addInterceptor(authInterceptor).addPathPatterns("/**")
//// }
//}

View File

@ -1,120 +0,0 @@
package kr.lunaticbum.back.lun.configs
import io.netty.channel.ChannelOption
import io.netty.handler.timeout.ReadTimeoutHandler
import io.netty.handler.timeout.WriteTimeoutHandler
import jakarta.servlet.ServletContext
import jakarta.servlet.ServletException
import kr.lunaticbum.back.lun.utils.LogService
import kr.lunaticbum.back.lun.utils.Logger
import lombok.RequiredArgsConstructor
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.http.client.reactive.ReactorClientHttpConnector
import org.springframework.web.WebApplicationInitializer
import org.springframework.web.context.ContextLoaderListener
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext
import org.springframework.web.reactive.function.client.ClientRequest
import org.springframework.web.reactive.function.client.ClientResponse
import org.springframework.web.reactive.function.client.ExchangeFilterFunction
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.servlet.DispatcherServlet
import org.springframework.web.util.DefaultUriBuilderFactory
import reactor.core.publisher.Mono
import reactor.netty.Connection
import reactor.netty.http.client.HttpClient
import java.time.Duration
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
@RequiredArgsConstructor
class WebConfig : WebApplicationInitializer {
lateinit var logService : LogService
var factory: DefaultUriBuilderFactory = DefaultUriBuilderFactory()
var httpClient: HttpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) // 10초
@Throws(ServletException::class)
override fun onStartup(servletContext: ServletContext) {
// Spring MVC 프로젝트 설정을 위해 작성하는 클래스의 객체를 생성한다.
val servletAppContext = AnnotationConfigWebApplicationContext()
servletAppContext.register(ServletAppContext::class.java)
// 요청 발생 시 요청을 처리하는 서블릿을 DispatcherServlet으로 설정해준다.
val dispatcherServlet = DispatcherServlet(servletAppContext)
val servlet = servletContext.addServlet("dispatcher", dispatcherServlet)
// 부가 설정
servlet.setLoadOnStartup(1)
servlet.addMapping("/")
// Bean을 정의하는 클래스를 지정한다.
val rootAppContext = AnnotationConfigWebApplicationContext()
rootAppContext.register(RootAppContext::class.java)
val listener = ContextLoaderListener(rootAppContext)
servletContext.addListener(listener)
}
@Bean
fun webClient(): WebClient {
/**
* 통신시 timeout 세팅
* - connect, read, write 모두 5000ms
*/
val httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.responseTimeout(Duration.ofMillis(5000))
.doOnConnected { conn: Connection ->
conn.addHandlerLast(ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS))
.addHandlerLast(WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS))
}
val webClient = WebClient.builder()
.baseUrl("https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w")
.clientConnector(ReactorClientHttpConnector(httpClient)) //생성한 HttpClient 연결
//Request Header 로깅 필터
.filter(
ExchangeFilterFunction.ofRequestProcessor { clientRequest: ClientRequest ->
logService.log(">>>>>>>>> REQUEST <<<<<<<<<<")
logService.log("Request: ${clientRequest.method()} ${clientRequest.url()}")
clientRequest.headers()
.forEach { (name: String?, values: MutableList<String?>?) ->
values.forEach(
Consumer<String> { value: String? ->
logService.log(
"${name} : ${value}"
)
})
}
Mono.just<ClientRequest>(clientRequest)
}
) //Response Header 로깅 필터
.filter(
ExchangeFilterFunction.ofResponseProcessor { clientResponse: ClientResponse ->
logService.log(">>>>>>>>>> RESPONSE <<<<<<<<<<")
clientResponse.headers().asHttpHeaders()
.forEach { (name: String?, values: MutableList<String?>?) ->
values.forEach(
Consumer<String> { value: String? ->
logService.log(
"${name} ${value}"
)
})
}
Mono.just<ClientResponse>(clientResponse)
}
)
.defaultHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8") //기본 헤더설정
.build()
return webClient
}
}

View File

@ -38,14 +38,14 @@ class Telegram {
} }
@ResponseBody @ResponseBody
@GetMapping("webhook") @PostMapping("webhook")
fun test(@PathVariable path : String) { fun test(@RequestBody str : String) {
println("path >>> $path") println("path >>> $str")
val client = WebClient.create() // val client = WebClient.create()
client.get() // client.get()
.uri("https://api.telegram.org/${globalEvv.telegramBotKey}/getUpdates") // .uri("https://api.telegram.org/${globalEvv.telegramBotKey}/getUpdates")
.retrieve() // .retrieve()
.bodyToMono(String::class.java).block() ?: "FAIL" // .bodyToMono(String::class.java).block() ?: "FAIL"
} }
@ -63,7 +63,7 @@ class Telegram {
@Bean @Bean
@Scheduled(cron = "0 0 0/2 * * *") // @Scheduled(cron = "0 0 0/1 * * *") //
fun runJob() { fun runJob() {
try { try {
println("telegramBotKey >>>> ${globalEvv.telegramBotKey}") println("telegramBotKey >>>> ${globalEvv.telegramBotKey}")
@ -125,21 +125,28 @@ class Telegram {
} }
} }
fun qns(it : Int, msg : Message) { fun qns(it : String, msg : Message) {
var doSave = true
telegramService.has(it)?.subscribe { m -> telegramService.findById(it)?.subscribe( { m ->
println("pollingTelegramUpdate doOnSuccess m >>>> $m") println("pollingTelegramUpdate doOnSuccess m >>>> $m")
if (m == 0L) { if (m != null) {
if (msg.text?.contains("어디") == true) { if (msg.text?.contains("어디") == true) {
sendMsg()
} else { } else {
logService.log(msg.text ?: "NONE") logService.log(msg.text ?: "NONE")
} }
telegramService.save(msg)
} else { } else {
doSave = false
} }
} },{ e ->
e.printStackTrace()
},{
if (doSave) {
telegramService.save(msg)
sendMsg()
}
println("pollingTelegramUpdate doOnSuccess comp ")
})
} }
fun sendMsg() { fun sendMsg() {
val client = WebClient.create() val client = WebClient.create()

View File

@ -8,13 +8,13 @@ import org.springframework.web.servlet.view.ContentNegotiatingViewResolver
@RestController @RestController
@RequestMapping("/user") @RequestMapping("user")
class User { class User {
@GetMapping("join") @GetMapping("/join")
fun hello(httpServletRequest: HttpServletRequest): ModelAndView { fun hello(httpServletRequest: HttpServletRequest): ModelAndView {
println("onJoin") println("onJoin")
val vm = ModelAndView("join") val vm = ModelAndView()
vm.modelMap.put("ddd","asdas") vm.modelMap.put("ddd","asdas")
println("${vm.toString()}") println("${vm.toString()}")
return vm return vm

View File

@ -49,7 +49,7 @@ class From {
@Document(collection = "TelegramMessage") @Document(collection = "TelegramMessage")
class Message { class Message {
@Id @Id
var message_id: Int = 0 var message_id: String = ""
@BsonIgnore @BsonIgnore
var from: From? = null var from: From? = null
@ -81,6 +81,8 @@ interface TelegramRepository : ReactiveMongoRepository<Message,String> {
@Query("{id :?0}") @Query("{id :?0}")
fun count(id: Int): Mono<Long> fun count(id: Int): Mono<Long>
fun save(message: Message): Mono<Message>
} }
interface MsgService { interface MsgService {
fun findById(id: String): Mono<Message>? fun findById(id: String): Mono<Message>?
@ -106,7 +108,10 @@ class TelegramMsgService : MsgService {
} }
fun save(msg: Message) { fun save(msg: Message) {
telegramRepository.save(msg) println("saved msg before ${msg}")
logService.log("saved msg ${msg}") telegramRepository.save(msg).subscribe( { println("saved msg after ${it}") },{e -> e.printStackTrace()},{
println("saved msg comp")
})
} }
} }

View File

@ -1,6 +1,5 @@
package kr.lunaticbum.back.lun.utils package kr.lunaticbum.back.lun.utils
import kr.lunaticbum.back.lun.configs.WebConfig
import lombok.RequiredArgsConstructor import lombok.RequiredArgsConstructor
import org.apache.logging.log4j.util.InternalException import org.apache.logging.log4j.util.InternalException
import org.springframework.http.HttpMethod import org.springframework.http.HttpMethod

View File

@ -1,24 +1,35 @@
spring.application.name=lun spring.application.name=lun
server.port=443
#spring.datasource.url=jdbc:mariadb://localhost:3307/lun_db spring.datasource.username=c
spring.datasource.username=lun_admin spring.datasource.password=c
spring.datasource.password=VioPup*383
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
#spring.data.mongodb.host=mongodb://127.0.0.1 spring.datasource.url=b
spring.datasource.url=jdbc:mariadb://127.0.0.1:3307/lun_db spring.data.mongodb.uri=a
spring.data.mongodb.host=mongo.sbspace.synology.me/?authSource=admin spring.data.mongodb.authentication-database=admin
#///mogodb://mongo.sbspace.synology.me spring.data.mongodb.database=l
#spring.data.mongodb.host=mongo.sbspace.synology.me spring.thymeleaf.prefix=classpath:/templates/
#spring.data.mongodb.port=443 spring.thymeleaf.suffix=.html
spring.data.mongodb.username=lun_admin
spring.data.mongodb.password=VioPup*383
spring.data.mongodb.database=Telegram
#spring.main.web-application-type=SERVLET
#logging.level.org.springframework.boot.autoconfigure=ERROR
#spring.mvc.view.prefix=/templates
#spring.mvc.view.suffix=.html
#server.servlet.register-default-servlet=true
telegram.bot.key=1 telegram.bot.key=1
telegram.my.id=2 telegram.my.id=2
telegram.target.id=3 telegram.target.id=3
weather.api.key=3 weather.api.key=3
spring.data.mongodb.option.min-connection-per-host=0
spring.data.mongodb.option.max-connection-per-host=100
spring.data.mongodb.option.threads-allowed-to-block-for-connection-multiplier=5
spring.data.mongodb.option.server-selection-timeout=30000
spring.data.mongodb.option.max-wait-time=120000
spring.data.mongodb.option.max-connection-idle-time=0
spring.data.mongodb.option.max-connection-life-time=0
spring.data.mongodb.option.connect-timeout=10000
spring.data.mongodb.option.socket-timeout=0
spring.data.mongodb.option.socket-keep-alive=false
spring.data.mongodb.option.ssl-enabled=false
spring.data.mongodb.option.ssl-invalid-host-name-allowed=false
spring.data.mongodb.option.always-use-m-beans=false
spring.data.mongodb.option.heartbeat-socket-timeout=20000
spring.data.mongodb.option.heartbeat-connect-timeout=20000
spring.data.mongodb.option.min-heartbeat-frequency=500
spring.data.mongodb.option.heartbeat-frequency=10000
spring.data.mongodb.option.local-threshold=15

View File

@ -1,6 +1,5 @@
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <html lang="ko" xmlns:th="http://www.thymeleaf.org">
<html lang="ko">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -8,7 +7,7 @@
<style> <style>
table { table {
width: 280px; width: 280px;
height: 550px; height: 850px;
margin: auto; margin: auto;
} }