feat: JsonOrFormBindを追加

This commit is contained in:
usbharu 2023-10-08 15:00:22 +09:00
parent 6b01927133
commit 16462198f6
3 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,6 @@
package dev.usbharu.hideout.config
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class JsonOrFormBind()

View File

@ -0,0 +1,55 @@
package dev.usbharu.hideout.config
import org.slf4j.LoggerFactory
import org.springframework.core.MethodParameter
import org.springframework.web.bind.support.WebDataBinderFactory
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.method.annotation.ModelAttributeMethodProcessor
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.method.support.ModelAndViewContainer
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor
class JsonOrFormModelMethodProcessor(
private val modelAttributeMethodProcessor: ModelAttributeMethodProcessor,
private val requestResponseBodyMethodProcessor: RequestResponseBodyMethodProcessor
) : HandlerMethodArgumentResolver {
override fun supportsParameter(parameter: MethodParameter): Boolean {
return parameter.hasParameterAnnotation(JsonOrFormBind::class.java)
}
private val isJsonRegex = Regex("application/((\\w*)\\+)?json")
override fun resolveArgument(
parameter: MethodParameter,
mavContainer: ModelAndViewContainer?,
webRequest: NativeWebRequest,
binderFactory: WebDataBinderFactory?
): Any? {
val contentType = webRequest.getHeader("Content-Type").orEmpty()
logger.trace("ContentType is {}", contentType)
if (contentType.contains(isJsonRegex)) {
logger.trace("Determine content type as json.")
return requestResponseBodyMethodProcessor.resolveArgument(
parameter,
mavContainer,
webRequest,
binderFactory
)
}
return try {
modelAttributeMethodProcessor.resolveArgument(parameter, mavContainer, webRequest, binderFactory)
} catch (e: Exception) {
try {
requestResponseBodyMethodProcessor.resolveArgument(parameter, mavContainer, webRequest, binderFactory)
} catch (e: Exception) {
logger.warn("Failed to bind request", e)
}
}
}
companion object {
val logger = LoggerFactory.getLogger(JsonOrFormModelMethodProcessor::class.java)
}
}

View File

@ -0,0 +1,30 @@
package dev.usbharu.hideout.config
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor
@Configuration
class MvcConfigurer(private val jsonOrFormModelMethodProcessor: JsonOrFormModelMethodProcessor) : WebMvcConfigurer {
override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) {
resolvers.add(jsonOrFormModelMethodProcessor)
}
}
@Configuration
class JsonOrFormModelMethodProcessorConfig {
@Bean
fun jsonOrFormModelMethodProcessor(converter: List<HttpMessageConverter<*>>): JsonOrFormModelMethodProcessor {
return JsonOrFormModelMethodProcessor(
ServletModelAttributeMethodProcessor(true),
RequestResponseBodyMethodProcessor(
converter
)
)
}
}