[JAVA] Bind the request to any class and receive it

Overview

When you want to get headers, parameters, etc. from "HttpServeletRequest" For the time being

public Oject sample(HttpServletRequest request) {
    //processing
}

If you do, you can do it in the controller class, Since the responsibility of the controller class increases, I wanted to bind and receive only the required values to the appropriate objects.

Method

You should use HandlerMethodArgumentResolver!

Details

I just want to understand how to use HandlerMethodArgumentResolver Try to easily receive the value of the request parameter in your own class instead of String

Class that receives parameters

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

@Getter
@AllArgsConstructor
@ToString
public class SampleArgument {
    private String value;

    public static SampleArgument of(String value) {
        return new SampleArgument(value);
    }
}

For my personal taste, instantiation is possible with the ʻofmethod. A simple class that holds the string received as an argument invalue`.

HandlerMethodArgumentResolver A class for binding to any class in the subject

import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

@Component
public class SampleResolver implements HandlerMethodArgumentResolver {

    //Details are omitted. .. ResolveArgument is executed only if true
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return true;
    }

    //The object returned here will be available as an argument
    @Override
    public Object resolveArgument(
            MethodParameter       parameter,
            ModelAndViewContainer mavContainer,
            NativeWebRequest      webRequest,
            WebDataBinderFactory  binderFactory
    ) throws Exception {

        String value = webRequest.getParameter("value");
        return SampleArgument.of(value);
    }
}

Implements the HandlerMethodArgumentResolver interface. Here, @Component is added to register as a bean.

Enable the implemented HandlerMethodArgumentResolver

import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;

@Configuration
@AllArgsConstructor
public class HandlerMethodArgumentResolverConfiguration implements WebMvcConfigurer {
    private SampleResolver sampleResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(sampleResolver);
    }
}

Since I added @Component earlier, Resolver receives it in the constructor (self-propelled generation with @AllArgsConstructor) The point is -Implementing the WebMvcConfigurer interface -Give @Configuration to the class After that, add the Resolver implemented in the list with the implementation method of ʻaddArgumentResolvers` and it's OK!

Operation check

We have prepared the following controllers.

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/HandlerMethodArgumentResolver")
@Slf4j
public class HandlerMethodArgumentResolverController {
    @GetMapping("/sample")
    @ResponseBody
    public SampleArgument sample(SampleArgument sampleArgument) {
        log.info("sampleArgument: {}", sampleArgument);
        return sampleArgument;
    }
}

http://localhost:8080/HandlerMethodArgumentResolver/sample?value=HelloWorld When you access

sampleArgument: SampleArgument(value=HelloWorld)

I was able to confirm that I was able to bind to my own class! !!

Recommended Posts

Bind the request to any class and receive it
[Code golf] Deflate the code and submit it to AtCoder [Compressed golf]
How to use the wrapper class
"Wait for the process to finish." And kill the process because it remains.
Easy to understand the difference between Ruby instance method and class method.
Add the pre-built jar library to Android and call it in the framework
Add the date to the GC statistics acquired by gcutil and output it.
Confirmation and refactoring of the flow from request to controller in [httpclient]
Is it possible to put the library (aar) in the Android library (aar) and use it?
[Java] How to use the File class
Recreate the container and then start it
[Java] How to use the HashMap class
[Processing × Java] How to use the class
How to find the tens and ones
[Java] How to use the Calendar class
If it is Ruby, it is efficient to make it a method and stock the processing.
[Ruby] How to calculate the total amount using the initialize method and class variables
I want to recursively get the superclass and interface of a certain class
[Java] How to use FileReader class and BufferedReader class
About next () and nextLine () of the Scanner class
How to find the total score and average score
[Java] How to use Calendar class and Date class
I want to morphologically analyze the log in the DB and put it in the DB to classify messages 1
Pass arguments to the method and receive the result of the operation as a return value