본문 바로가기

Web/spring

[Spring framework Web MVC docs] 1.3.3 Handler Methods

728x90

틀린 해석이 있다면 알려주세요

 


 

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-methods

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

 

 

@RequestMapping

 

controller method argument

WebRequest

ServletRequest

ServletResponse

HttpSession

PushBuilder

Principal

HttpMethod

Locale

TimeZone + ZoneId

InputStream, Reader

OutputStream, Writer

@PathVariable

@MatrixVariable

@RequestParam

@RequestHeader

@CookieValue

@RequestBody

HttpEntity<B>

@RequestPart

Map, Mdodel, ModelMap

RedirectAttributes

@ModelAttribute

Errors, BindingResult

SessionStatus + @SessionAttributes

UriComponentsBuilder

@SessionAttribute

@requestAttribute

++ any argument 일 경우 메서드 인수가 이 표의 이전 값과 일치하지 않고 단순 유형( BeanUtils#isSimpleProperty 에 의해 결정됨 )인 경우 @RequestParam. 그렇지 않으면 @ModelAttribute.

 

Return Values

@ResponseBody - HttpMessageConverter 

HttpEntity<B>, ResponseEntity<B> -  The return value that specifies the full response 

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-responseentity

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

HttpHeaders 

ErrorResponse

ProblemDetail

String - ViewResolver , @ModelAttribute

View - View + @ModelAttribute

Model - RequestToViewNameTranslator

@ModelAttribute - added to the model, through RequestToViewNameTranslate

ModelAndView object

void 

DefferredResult<V> - 모든 스레드에서 반환값을 비동기적으로 생성

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

Callable<V> - Callable 

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async-callable

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

ListenableFuture<V>, CompletionStage<V>, CompletableFuture<V> - DeferredResult 대안

ResponseBodyEmitter, SseEmitter - HttpMessageConverter 구현을 통해 비동기적으로 보냄 ResponseEntity

StreamingResponseBody - OutputStream 응답에 비동기처리

ReactiveAdapterRegister 

기타반환값

 

 

 

Type Conversion

보통 String 기반 요청 입력이나,

WebDataBinder 또는 Formatters 하여 단순 유형 지원(int, long, Date 등)

FormattingConversionService 

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#format

 

Core Technologies

In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do

docs.spring.io

 

null 허용 하려는 경우 @Nullable 표시 또는

@RequestParam required=false

 

 

 

Matrix Variables

// GET /pets/42;q=11;r=22

@GetMapping("/pets/{petId}")
public void findPet(@PathVariable String petId, @MatrixVariable int q) {

    // petId == 42
    // q == 11
}

 

정확한 변수 지정

// GET /owners/42;q=11/pets/21;q=22

@GetMapping("/owners/{ownerId}/pets/{petId}")
public void findPet(
        @MatrixVariable(name="q", pathVar="ownerId") int q1,
        @MatrixVariable(name="q", pathVar="petId") int q2) {

    // q1 == 11
    // q2 == 22
}

 

기본값 지정

// GET /pets/42

@GetMapping("/pets/{petId}")
public void findPet(@MatrixVariable(required=false, defaultValue="1") int q) {

    // q == 1
}

 

MultiValueMap

// GET /owners/42;q=11;r=12/pets/21;q=22;s=23

@GetMapping("/owners/{ownerId}/pets/{petId}")
public void findPet(
        @MatrixVariable MultiValueMap<String, String> matrixVars,
        @MatrixVariable(pathVar="petId") MultiValueMap<String, String> petMatrixVars) {

    // matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
    // petMatrixVars: ["q" : 22, "s" : 23]
}

 

 

 

@RequestParam

쿼리 매개변수 바인딩

 

@Controller
@RequestMapping("/pets")
public class EditPetForm {

    // ...

    @GetMapping
    public String setupForm(@RequestParam("petId") int petId, Model model) { 
        Pet pet = this.clinic.loadPet(petId);
        model.addAttribute("pet", pet);
        return "petForm";
    }

    // ...

}

 

required 플래그 설정 가능,

Optional 래퍼 사용 가능

 

@RequestParam 지정 시

Map<String, String> , MultiValueMap<String, String>

 

 

 

 

@RequestHeader

 

Host                    localhost:8080
Accept                  text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Language         fr,en-gb;q=0.7,en;q=0.3
Accept-Encoding         gzip,deflate
Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive              300

가져오는 방법

 

@GetMapping("/demo")
public void handle(
        @RequestHeader("Accept-Encoding") String encoding, (1)
        @RequestHeader("Keep-Alive") long keepAlive) { (2)
    //...
}

 

 

 

@CookieValue 

JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84

가져오는 방법

@GetMapping("/demo")
public void handle(@CookieValue("JSESSIONID") String cookie) { 
    //...
}

 

 

@ModelAttribute

data binding -> 개별 쿼리 매개변수 구문 분석 없이 바로 사용가능

Converter<String ,T>

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) { 
    // method logic...
}

또는 명시적 사용

@PutMapping("/accounts/{account}")
public String save(@ModelAttribute("account") Account account) { 
    // ...
}

@SessionAttributes 는 httpsession dptj rjator

convert 값 일치 여부 확인하여 가져옴

 

Data binding can result in errors. By default, a BindException is raised. However, to check for such errors in the controller method, you can add a BindingResult argument immediately next to the @ModelAttribute, as the following example shows:

 

 

@ModelAttribute
public AccountForm setUpForm() {
    return new AccountForm();
}

@ModelAttribute
public Account findAccount(@PathVariable String accountId) {
    return accountRepository.findOne(accountId);
}

@PostMapping("update")
public String update(@Valid AccountForm form, BindingResult result,
        @ModelAttribute(binding=false) Account account) { 
    // ...
}

 

 

Valid 사용

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) { 
    if (result.hasErrors()) {
        return "petForm";
    }
    // ...
}

 

 

 

 

@SessionAttributes

@Controller
@SessionAttributes("pet") 
public class EditPetForm {

    // ...

    @PostMapping("/pets/{id}")
    public String handle(Pet pet, BindingResult errors, SessionStatus status) {
        if (errors.hasErrors) {
            // ...
        }
        status.setComplete(); 
        // ...
    }
}

모델 pet 으로 받아 유지 시킴

 

 

@SessionAttribute

전역적이거나 존재하지않을 수 있을 경우 사용

@RequestMapping("/")
public String handle(@SessionAttribute User user) { 
    // ...
}

 

sessionAttributes 설명대로 사용할 것

 

 

 

@RequestAttribute

@SessionAttribute 유사한 방법으로

기존 종속된 요청들 (Filter, HandlerInterceptor)에 액세스

@GetMapping("/")
public String handle(@RequestAttribute Client client) { 
    // ...
}

 

 

Redirect Attributes

RequestMappingHandlerAdapter 라는 플래그 제공

리다이렉션 되는 경우 기본값을 사용하지 않아야  ignoreDefaultModelOnRedirect

 

RedirectView 를 사용해서 RedirectAttributes

 

플래시 속성 사용

 

 

플래시 속성

플래시 속성은 리디렉션 후 요청에 사용할 수 있도록 리디렉션 전에(일반적으로 세션에서) 일시적으로 저장되며 즉시 제거

 

lash attribute support is always “on” and does not need to be enabled explicitly. However, if not used, it never causes HTTP session creation. On each request, there is an “input” FlashMap with attributes passed from a previous request (if any) and an “output” FlashMap with attributes to save for a subsequent request. Both FlashMap instances are accessible from anywhere in Spring MVC through static methods in RequestContextUtils.

Annotated controllers typically do not need to work with FlashMap directly. Instead, a @RequestMapping method can accept an argument of type RedirectAttributes and use it to add flash attributes for a redirect scenario. Flash attributes added through RedirectAttributes are automatically propagated to the “output” FlashMap. Similarly, after the redirect, attributes from the “input” FlashMap are automatically added to the Model of the controller that serves the target URL.

 

 

Multipart

MultipartResolver 를 활성화하고, post 요청 내용에 multipart/form-data 가 있을 경우 액세스 가능

 

@Controller
public class FileUploadController {

    @PostMapping("/form")
    public String handleFormUpload(@RequestParam("name") String name,
            @RequestParam("file") MultipartFile file) {

        if (!file.isEmpty()) {
            byte[] bytes = file.getBytes();
            // store the bytes somewhere
            return "redirect:uploadSuccess";
        }
        return "redirect:uploadFailure";
    }
}

List<MultipartFile> 로 여러개 받을 수 있음

@RequestParam 으로 선언시 멀티파트파일로 채워짐

Map<String, MultipartFile> , MultiValueMap<String, MultipartFile>

 

 

 

class MyForm {

    private String name;

    private MultipartFile file;

    // ...
}

@Controller
public class FileUploadController {

    @PostMapping("/form")
    public String handleFormUpload(MyForm form, BindingResult errors) {
        if (!form.getFile().isEmpty()) {
            byte[] bytes = form.getFile().getBytes();
            // store the bytes somewhere
            return "redirect:uploadSuccess";
        }
        return "redirect:uploadFailure";
    }
}

 

 

RESTful 사용시

POST /someUrl
Content-Type: multipart/mixed

--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="meta-data"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit

{
    "name": "value"
}
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="file-data"; filename="file.properties"
Content-Type: text/xml
Content-Transfer-Encoding: 8bit
... File Data ...

 

form-data 의 meta-data, file-data << 

 

요청을 받을 때

@PostMapping("/")
public String handle(@RequestPart("meta-data") MetaData metadata,
        @RequestPart("file-data") MultipartFile file) {
    // ...
}

 

요청 + valid  유효성 검사 처리시 (400)

@PostMapping("/")
public String handle(@Valid @RequestPart("meta-data") MetaData metadata,
        BindingResult result) {
    // ...
}

 

 

 

@RequestBody

요청 받은 body 값을 가져옴

@PostMapping("/accounts")
public void handle(@RequestBody Account account) {
    // ...
}

@Valid 유효성 검사 처리시 (400 유효성검사)

@PostMapping("/accounts")
public void handle(@Valid @RequestBody Account account, BindingResult result) {
    // ...
}

 

HttpEntity

@RequestBody 와 거의 비슷하지만

요청 헤더와 바디 컨테이너 개체를 가져옴

 

RequestBody, RequestHeader 둘다 포함

@PostMapping("/accounts")
public void handle(HttpEntity<Account> entity) {
    // ...
}

 

 

 


이제 응답해줄때 내용!!!

 

 

@ResponseBody

 

@ResponseBody 를 사용하여 응답 내용을 직렬화함

HttpMessageConverter

 

예시

@GetMapping("/accounts/{id}")
@ResponseBody
public Account handle() {
    // ...
}

사용할 수 있는 유형

Asynchronous Requests - https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

Reactive Types - https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async-reactive-types

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

 

 

JSON 으로 결합가능

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-jackson

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

 

 

 

@ResponseEntity

@ResponseBody+ 헤더가 있음

@GetMapping("/something")
public ResponseEntity<String> handle() {
    String body = ... ;
    String etag = ... ;
    return ResponseEntity.ok().eTag(etag).body(body);
}

 

 

JSON

jackson JSON 라이브러리 지원함

 

Spring MVC provides built-in support for Jackson’s Serialization Views, which allow rendering only a subset of all fields in an Object. To use it with @ResponseBody or ResponseEntity controller methods, you can use Jackson’s @JsonView annotation to activate a serialization view class, as the following example shows:

 

 

 

@JsonView 를 사용

@RestController
public class UserController {

    @GetMapping("/user")
    @JsonView(User.WithoutPasswordView.class)
    public User getUser() {
        return new User("eric", "7!jd#h23");
    }
}

public class User {

    public interface WithoutPasswordView {};
    public interface WithPasswordView extends WithoutPasswordView {};

    private String username;
    private String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @JsonView(WithoutPasswordView.class)
    public String getUsername() {
        return this.username;
    }

    @JsonView(WithPasswordView.class)
    public String getPassword() {
        return this.password;
    }
}

@JsonView뷰 클래스의 배열을 허용하지만 컨트롤러 메서드당 하나만 지정할 수 있습니다. 여러 보기를 활성화해야 하는 경우 복합 인터페이스를 사용할 수 있습니다.

 

 

이를 프로그래밍방식으로 반환 값 래핑 하는 방법

 

@RestController
public class UserController {

    @GetMapping("/user")
    public MappingJacksonValue getUser() {
        User user = new User("eric", "7!jd#h23");
        MappingJacksonValue value = new MappingJacksonValue(user);
        value.setSerializationView(User.WithoutPasswordView.class);
        return value;
    }
}

 

그리고 이렇게 클래스 모델에 추가할 수 있음

@Controller
public class UserController extends AbstractController {

    @GetMapping("/user")
    public String getUser(Model model) {
        model.addAttribute("user", new User("eric", "7!jd#h23"));
        model.addAttribute(JsonView.class.getName(), User.WithoutPasswordView.class);
        return "userView";
    }
}

 

728x90