1. Hello World
コントローラクラスを作成します。
最初にテストを記述します。
package com.example; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class DemoApplicationTests { @Autowired TestRestTemplate template; @Test public void contextLoads() { ResponseEntity<String> res = template.getForEntity("/", String.class); assertThat(res.getStatusCode(), is(HttpStatus.OK)); assertThat(res.getBody(), is("Hello World!!")); } }
次に、IndexControllerを作成します。
package com.example; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @GetMapping("/") public String index() { return "Hello World!!"; } }
REST のコントローラには、@RestController アノテーションを使ってクラスを作成します。 コントローラのメソッドには URL のマッピングを設定します。 ここで使用している GetMapping 以外に、PostMapping や、PutMpping、DeleteMapping 等があります。
最初のステップでは、Hello World!! という文字列を返しました。
2. コントローラのメソッドの引数
コントローラのメソッドは、HttpServletRequest や HttpServletResponse やその他さまざまなオブジェクトを受け取ることができます。
package com.example; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Objects; @RestController public class IndexController { @GetMapping("/") public String index(HttpServletRequest req, HttpServletResponse res) { Objects.nonNull(req); Objects.nonNull(res); return "Hello World!!"; } }
3. PathVariable
URLパスの変数の値を受け取ることができます。
package com.example; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @GetMapping("/{id}") public String index(@PathVariable String id) { return "ID: " + id; } }
package com.example; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class DemoApplicationTests { @Autowired TestRestTemplate template; @Test public void contextLoads() { ResponseEntity<String> res = template.getForEntity("/123", String.class); assertThat(res.getStatusCode(), is(HttpStatus.OK)); assertThat(res.getBody(), is("ID: 123")); } }
4. Request パラメータ
Request パラメータを受け取ることももちろんできます。
package com.example; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @GetMapping("/foo") public String index(@RequestParam String id) { return "ID: " + id; } }
package com.example; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class DemoApplicationTests { @Autowired TestRestTemplate template; @Test public void contextLoads() { ResponseEntity<String> res = template.getForEntity("/foo?id=bar", String.class); assertThat(res.getStatusCode(), is(HttpStatus.OK)); assertThat(res.getBody(), is("ID: bar")); } }
ModelAttribute
Request パラメータが多い場合等は、ModelAttribute を使って、Request パラメータの値が設定されたオブジェクトを受け取ることができるようにすることができます。
package com.example; public class Foo { private String id; public void setId(String id) { this.id = id; } public String getId() { return id; } }
package com.example; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @GetMapping("/foo") public String index(@ModelAttribute Foo foo) { return "ID: " + foo.getId(); } }
package com.example; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class DemoApplicationTests { @Autowired TestRestTemplate template; @Test public void contextLoads() { ResponseEntity<String> res = template.getForEntity("/foo?id=bar", String.class); assertThat(res.getStatusCode(), is(HttpStatus.OK)); assertThat(res.getBody(), is("ID: bar")); } }
5. HandlerMethodArgumentResolver
HandlerMethodArgumentResolver の実装クラスを作成して、任意のオブジェクトをコントローラのメソッドで受け取ることができるようにすることができます。 Spring Security を使ってログインしているユーザの Principal をコントローラで受け取る場合などこの仕組みが多く使用されています。
package com.example; public class Foo { public final String foo = "foo"; }
package com.example; import org.springframework.core.MethodParameter; 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; public class FooHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return Foo.class.isAssignableFrom(parameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { return new Foo(); } }
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import java.util.List; @SpringBootApplication public class DemoApplication extends WebMvcConfigurerAdapter { @Override public void addArgumentResolvers( List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new FooHandlerMethodArgumentResolver()); } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
package com.example; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @GetMapping("/") public String index(Foo foo) { return foo.foo; } }
package com.example; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class DemoApplicationTests { @Autowired TestRestTemplate template; @Test public void contextLoads() { ResponseEntity<String> res = template.getForEntity("/", String.class); assertThat(res.getStatusCode(), is(HttpStatus.OK)); assertThat(res.getBody(), is("foo")); } }