
μ€λμ μ€νλ§ mvc μμ μ 곡νλ ArgumentResolverλ₯Ό μ§μ ꡬννλ λ°©λ²μ μ€λͺ νλ €κ³ ν©λλ€.
컨νΈλ‘€λ¬ λ©μλ νλΌλ―Έν°μ Model, ServletRequest λ±λ± μ μλ§ νλ©΄ μ½κ² κ°μ Έλ€ μΈ μ μλ μ΄μ λ μ΄ ArgumentResolver λλΆμΈλ°μ, 컀μ€ν νκ² λ§λ€μ΄μ μμ£Ό μ¬μ©νκΈ°λ ν©λλ€.
μλ£λ₯Ό μ°Ύλ€ λ³΄λ μ΄λ Έν μ΄μ μ λΆμ΄λ κ²½μ°λ μκ³ μλΆμ΄κΈ°λ νλλ°
μ μκ°μ String, Integer λ± λ²μ©μ μΈ ν΄λμ€κ° μ¬μ©λλ κ²½μ°λ μλ³μ μν΄ μ΄λ Έν μ΄μ μ λΆμ΄κ³
ν΄λμ€κ° λͺ ννκ² κ΅¬λΆλλ€λ©΄ μ΄λ Έν μ΄μ μ λΆμ΄λ κ²μ λΆνμνλ€κ³ μκ°ν©λλ€.
μμ λ₯Ό λ§λ€κΈ° μν΄ λͺκ°μ§ μΆκ° μμ‘΄μ±μ μΆκ°νμ΅λλ€.
// build.gradle
// apache lang3μ user-agent-parserλ₯Ό ν¨κ» μΆκ°νμ΅λλ€.
plugins {
id 'org.springframework.boot' version '2.2.6.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.larry.blog'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
// https://mvnrepository.com/artifact/com.github.ua-parser/uap-java
compile group: 'com.github.ua-parser', name: 'uap-java', version: '1.4.3'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
}
test {
useJUnitPlatform()
}
Ipλ₯Ό νμ±νλ κΈ°λ₯κ³Ό User-Agent μ 보λ₯Ό νμ±ν μ 보 λ κ°μ§λ₯Ό κ°κ° κ°μ Έμ€κΈ° μν΄μ μλμ κ°μ΄ λ κ°μ ArgumentResolverλ₯Ό λ§λ€μμ΅λλ€.
public class ClientArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(Client.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Parser parser = new Parser();
return parser.parse(webRequest.getHeader("User-Agent"));
}
}
public class ParsedIpArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(ParsedIp.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
String ipAddress = request.getHeader("X-Forwarded-For");
return StringUtils.defaultString(ipAddress,
parameter.getParameterAnnotation(ParsedIp.class).defaultValue());
}
}
λ³΄ν΅ μΉμλ²λ₯Ό νλ‘μλ‘ μ΄μ©νλ κ²½μ° X-Forwarded-Forλ‘ Ipλ₯Ό κ°μ Έμ€λ―λ‘ (μλ κ²½μ°λ λ§μ΅λλ€! IPλ₯Ό νμ±νλ λ°©λ²μ λν΄μλ μΆκ° ν¬μ€ν νκ² μ΅λλ€.^^)
ν€λλ₯Ό κ°μ Έμ€κ³ λ§μ½ μλ€λ©΄ κΈ°λ³Έ κ°μ μ£Όλλ‘ λ§λ€μμ΅λλ€.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface ParsedIp {
String defaultValue() default "UNKNOWN";
}
μ€νλ§ MVC Configuration μ λ±λ‘ν΄ μ€λλ€.
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new ParsedIpArgumentResolver());
argumentResolvers.add(new ClientArgumentResolver());
}
}
μ¬κΈ°κΉμ§ νλ€λ©΄ μ¬μ©νλ μΌλ§ λ¨μμ΅λλ€!
@RestController
@Slf4j
public class MyController {
@GetMapping
public ResponseEntity<Void> ipTest(@ParsedIp(defaultValue = "Hello ip") String ip,
Client client) {
log.info("ip address: {}", ip);
log.info("client: {}", client.toString());
return ResponseEntity.ok().build();
}
}
컨νΈλ‘€λ¬ λ©μλμ μμ κ°μ΄ νμν νλΌλ―Έν°λ₯Ό μ νμ μΌλ‘ λ±λ‘νμ¬ μ¬μ©νλ©΄ λ©λλ€.
κ°λ¨ν ν μ€νΈλ₯Ό μν΄ μμ²μ ν΄λ³΄λ©΄ (λλ°μ΄μ€λ μμ΄ν¨λλ‘ νμ΅λλ€.)

νμ±λ κ²°κ³Όλ¬Όμ νμΈν μ μμ΅λλ€.

μ΄λ κ² ν΄μ κ°μμ νλ‘μ νΈμ μ μ©νκ² μ μ©νμκΈΈ λ°λλλ€~ππ
'νλ‘κ·Έλλ°' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
| [μ€νλ§] μ€νλ§μ μ΄ν΄νκΈ° μ΄λ €μ΄ μ΄μ . λ€μ€ μΈν°νμ΄μ€ μμ (0) | 2020.04.16 |
|---|---|
| http ν€λλ₯Ό μμ νκ² μ€μ νλ λ°©λ² (0) | 2020.04.15 |

μ΅κ·ΌλκΈ