Skip to content
Open
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
Binary file added .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
### 필요한건 Notion에 저장해놓을게요 양해부탁드려요..
https://www.notion.so/kkw01234/dbaf7c5999e04a39b8241682854ddfae

### 권한 요청 필요합니다
### 권한 요청 필요합니다
5 changes: 5 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
id("io.spring.dependency-management") version "1.0.9.RELEASE"
kotlin("jvm") version "1.3.72"
kotlin("plugin.spring") version "1.3.72"
kotlin("plugin.jpa") version "1.3.72"
}

group = "com.example"
Expand All @@ -17,9 +18,13 @@ repositories {

dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation ("org.springframework.boot:spring-boot-starter-aop")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
runtimeOnly("mysql:mysql-connector-java")
testImplementation("com.h2database:h2")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.example.kotlinweb

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.EnableAspectJAutoProxy

@EnableAspectJAutoProxy
@SpringBootApplication
class KotlinwebApplication

fun main(args: Array<String>) {
runApplication<KotlinwebApplication>(*args)
}
}
27 changes: 27 additions & 0 deletions src/main/kotlin/com/example/kotlinweb/aspect/BoardAspect.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.kotlinweb.aspect

import com.example.kotlinweb.model.Board
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.annotation.Pointcut
import org.springframework.stereotype.Component


@Aspect
@Component
class BoardAspect(
private val boardList: MutableList<Board>
){

@Before(value = "execution(* com.example.kotlinweb.service.BoardService.*(..)) && args(id))")
fun interceptBoard(joinPoint: JoinPoint, id:Int){
if(id <= 0) throw RuntimeException("1이상의 숫자를 입력해주세요")
if(id > boardList.size ) throw RuntimeException("게시글 개수보다 많습니다.")
}




}
16 changes: 16 additions & 0 deletions src/main/kotlin/com/example/kotlinweb/config/BoardConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.kotlinweb.config

import com.example.kotlinweb.model.Board
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class BoardConfig{


@Bean
fun boardList():MutableList<Board>{
return mutableListOf();
}

}
35 changes: 35 additions & 0 deletions src/main/kotlin/com/example/kotlinweb/config/WebConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.kotlinweb.config

import com.example.kotlinweb.interceptor.TokenInterceptor
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.filter.CharacterEncodingFilter
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer

@Configuration
class WebConfig(
private val tokenInterceptor: TokenInterceptor
): WebMvcConfigurer {

override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**")
.allowedMethods("GET", "PUT", "DELETE", "POST", "OPTIONS")
.allowedOrigins("*")
.allowedHeaders("*")
.allowCredentials(true)
}

@Bean
fun characterEncodingFilter(): CharacterEncodingFilter {
val characterEncodingFilter: CharacterEncodingFilter = CharacterEncodingFilter()
characterEncodingFilter.encoding = "UTF-8"
characterEncodingFilter.setForceEncoding(true)
return characterEncodingFilter
}

override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(tokenInterceptor).addPathPatterns("/**")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.example.kotlinweb.controller

import com.example.kotlinweb.model.Board
import com.example.kotlinweb.model.request.BoardRequest
import com.example.kotlinweb.model.response.Response
import com.example.kotlinweb.service.BoardService
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.*

@RestController
class BoardController(
private val boardService: BoardService
){

@PostMapping("/board")
fun postBoard(@RequestBody boardRequest:BoardRequest): Response<Board> {
return Response(HttpStatus.CREATED, "create", boardService.createBoard(boardRequest));
}

@GetMapping("/board")
fun findAllBoard(): Response<List<Board>> {
return Response(HttpStatus.OK, "findAll", boardService.findAllBoard())
}

@GetMapping("/board/{id}")
fun findBoard(@PathVariable id:Long): Response<Board> {
return Response(HttpStatus.OK, "find", boardService.findBoard(id))
}

@DeleteMapping("/board/{id}")
fun deleteBoard(@PathVariable id:Long): Response<Boolean> {
return Response(HttpStatus.OK, "delete", boardService.deleteBoard(id))
}

@PutMapping("/board/{id}")
fun update(@PathVariable id:Long, @RequestBody boardRequest:BoardRequest): Response<Board> {
return Response(HttpStatus.OK, "update", boardService.updateBoard(id, boardRequest))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ class HealthController{
@get:GetMapping(value = ["/health_check.html"])
val ratingStatus: ResponseEntity<String>
get() = ResponseEntity("Health", HttpStatus.OK)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.kotlinweb.controller

class UserController(

){

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.example.kotlinweb.exception

import com.example.kotlinweb.model.response.Response
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.client.HttpClientErrorException

@ControllerAdvice
class ControllerAdvice(){

@ExceptionHandler(Exception::class)
private fun handleUnexpectedHandler(exception: Exception): ResponseEntity<Response<*>> {
return makeResponseException(exception)
}

private fun makeResponseException(exception: Exception): ResponseEntity<Response<*>>{
return when(exception){
is HttpClientErrorException.BadRequest ->{
makeResponse(exception.message, HttpStatus.BAD_REQUEST)
}
else -> {
makeResponse(exception.message,HttpStatus.INTERNAL_SERVER_ERROR)
}
}
}
private fun makeResponse(message:String?, status:HttpStatus, data:Any? = null):ResponseEntity<Response<*>>{
return ResponseEntity(Response(code = status, message = message?.let { message }
?: "", data = data), status)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.kotlinweb.interceptor

import com.example.kotlinweb.model.UserContext
import com.example.kotlinweb.service.UserService
import org.springframework.stereotype.Component
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter
import java.lang.RuntimeException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

@Component
class TokenInterceptor(
private val userService: UserService
): HandlerInterceptorAdapter(){
@Throws(Exception::class)
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
val headerMap: MutableMap<String, String> = HashMap()
request.headerNames.toList().map { headerMap[it.toLowerCase()] = request.getHeader(it) }

val token = headerMap["authorization"] ?: throw RuntimeException("not found authorization token")

val user = userService.getUserByToken(token)
UserContext.setUser(user)

return super.preHandle(request, response, handler)
}

@Throws(Exception::class)
override fun postHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any, modelAndView: ModelAndView?) {
UserContext.removeAll()
super.postHandle(request, response, handler, modelAndView)
}
}
15 changes: 15 additions & 0 deletions src/main/kotlin/com/example/kotlinweb/model/Board.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.kotlinweb.model

import javax.persistence.*

@Entity
class Board(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id:Long? = null,
var title:String,
var content:String,
@ManyToOne
@JoinColumn(name = "userId")
val user:User
)
15 changes: 15 additions & 0 deletions src/main/kotlin/com/example/kotlinweb/model/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.kotlinweb.model

import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id

@Entity
class User(
@Id
val id: String,
val password: String,
val name: String,
var token: String? = null
)
20 changes: 20 additions & 0 deletions src/main/kotlin/com/example/kotlinweb/model/UserContext.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.kotlinweb.model

object UserContext{

private val exception = ThreadLocal<Exception>()
private val user = ThreadLocal<User>()

fun setUser(user:User) = this.user.set(user)

fun getUser() = this.user.get()

fun removeUser() = user.remove()

fun removeException() = exception.remove()

fun removeAll() {
removeUser()
removeException()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.example.kotlinweb.model.request

class BoardRequest(
val title:String,
val content:String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.kotlinweb.model.response

import org.springframework.http.HttpStatus

class Response<T>(
val code:HttpStatus,
val message:String,
val data: T
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.example.kotlinweb.repository

import com.example.kotlinweb.model.Board
import org.springframework.data.jpa.repository.JpaRepository

interface BoardRepository: JpaRepository<Board, Long>{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.kotlinweb.repository

import com.example.kotlinweb.model.User
import org.springframework.data.jpa.repository.JpaRepository

interface UserRepository: JpaRepository<User, String>{
fun findByToken(token:String):User?
}
43 changes: 43 additions & 0 deletions src/main/kotlin/com/example/kotlinweb/service/BoardService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.example.kotlinweb.service

import com.example.kotlinweb.model.Board
import com.example.kotlinweb.model.UserContext
import com.example.kotlinweb.model.request.BoardRequest
import com.example.kotlinweb.repository.BoardRepository
import com.example.kotlinweb.repository.UserRepository
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import java.lang.RuntimeException
import javax.transaction.Transactional

@Service
class BoardService(
private val boardRepository: BoardRepository
){

fun createBoard(boardRequest:BoardRequest):Board{
val board = Board(null, boardRequest.title, boardRequest.content, UserContext.getUser())
return boardRepository.save(board)
}

fun findBoard(id:Long):Board{
return boardRepository.findByIdOrNull(id) ?: throw RuntimeException("not found board")
}
fun findAllBoard():List<Board>{
return boardRepository.findAll()
}

fun deleteBoard(id:Long):Boolean{
boardRepository.deleteById(id)
return true
}

@Transactional
fun updateBoard(id:Long, boardRequest: BoardRequest):Board{
val board = boardRepository.findByIdOrNull(id) ?: throw RuntimeException("not found board")
board.title = boardRequest.title
board.content = boardRequest.content
return board
}

}
Loading