Merge pull request #8154 from sjmillington/rest-move-2
[BAEL-18365] Spring rest move 2
This commit is contained in:
		
						commit
						fbf857ce85
					
				| @ -8,3 +8,4 @@ This module contains articles about Spring Boot with Spring Data | |||||||
| - [Rendering Exceptions in JSON with Spring](https://www.baeldung.com/spring-exceptions-json) | - [Rendering Exceptions in JSON with Spring](https://www.baeldung.com/spring-exceptions-json) | ||||||
| - [Disable Spring Data Auto Configuration](https://www.baeldung.com/spring-data-disable-auto-config) | - [Disable Spring Data Auto Configuration](https://www.baeldung.com/spring-data-disable-auto-config) | ||||||
| - [Repositories with Multiple Spring Data Modules](https://www.baeldung.com/spring-multiple-data-modules) | - [Repositories with Multiple Spring Data Modules](https://www.baeldung.com/spring-multiple-data-modules) | ||||||
|  | - [Spring Custom Property Editor](https://www.baeldung.com/spring-mvc-custom-property-editor) | ||||||
|  | |||||||
| @ -8,3 +8,7 @@ This module contains articles about administering a Spring Boot runtime | |||||||
|  - [Logging HTTP Requests with Spring Boot Actuator HTTP Tracing](https://www.baeldung.com/spring-boot-actuator-http) |  - [Logging HTTP Requests with Spring Boot Actuator HTTP Tracing](https://www.baeldung.com/spring-boot-actuator-http) | ||||||
|  - [How to Disable Console Logging in Spring Boot](https://www.baeldung.com/spring-boot-disable-console-logging) |  - [How to Disable Console Logging in Spring Boot](https://www.baeldung.com/spring-boot-disable-console-logging) | ||||||
|  - [Spring Boot Embedded Tomcat Logs](https://www.baeldung.com/spring-boot-embedded-tomcat-logs)  |  - [Spring Boot Embedded Tomcat Logs](https://www.baeldung.com/spring-boot-embedded-tomcat-logs)  | ||||||
|  |  - [How to Change the Default Port in Spring Boot](https://www.baeldung.com/spring-boot-change-port) | ||||||
|  |  - [Project Configuration with Spring](https://www.baeldung.com/project-configuration-with-spring) | ||||||
|  |  - [CORS with Spring](https://www.baeldung.com/spring-cors) | ||||||
|  |  - [Spring – Log Incoming Requests](https://www.baeldung.com/spring-http-logging) | ||||||
| @ -32,6 +32,12 @@ | |||||||
|             <artifactId>spring-boot-starter-test</artifactId> |             <artifactId>spring-boot-starter-test</artifactId> | ||||||
|             <scope>test</scope> |             <scope>test</scope> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>commons-io</groupId> | ||||||
|  |             <artifactId>commons-io</artifactId> | ||||||
|  |             <version>2.6</version> | ||||||
|  |         </dependency> | ||||||
| 
 | 
 | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.springframework.boot</groupId> |             <groupId>org.springframework.boot</groupId> | ||||||
| @ -57,6 +63,10 @@ | |||||||
|             <artifactId>spring-boot-admin-starter-client</artifactId> |             <artifactId>spring-boot-admin-starter-client</artifactId> | ||||||
|             <version>${spring-boot-admin-starter-client.version}</version> |             <version>${spring-boot-admin-starter-client.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.security</groupId> | ||||||
|  |             <artifactId>spring-security-test</artifactId> | ||||||
|  |         </dependency> | ||||||
| 
 | 
 | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>com.h2database</groupId> |             <groupId>com.h2database</groupId> | ||||||
|  | |||||||
| @ -0,0 +1,15 @@ | |||||||
|  | package com.baeldung.sampleapp.config; | ||||||
|  | 
 | ||||||
|  | import org.springframework.boot.SpringApplication; | ||||||
|  | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; | ||||||
|  | import org.springframework.context.annotation.ComponentScan; | ||||||
|  | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||||||
|  | 
 | ||||||
|  | @EnableAutoConfiguration | ||||||
|  | @ComponentScan("com.baeldung.sampleapp") | ||||||
|  | public class MainApplication implements WebMvcConfigurer { | ||||||
|  | 
 | ||||||
|  |     public static void main(final String[] args) { | ||||||
|  |         SpringApplication.run(MainApplication.class, args); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | package com.baeldung.sampleapp.config; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.http.client.ClientHttpRequestInterceptor; | ||||||
|  | import org.springframework.util.CollectionUtils; | ||||||
|  | import org.springframework.web.client.RestTemplate; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.interceptors.RestTemplateHeaderModifierInterceptor; | ||||||
|  | 
 | ||||||
|  | @Configuration | ||||||
|  | public class RestClientConfig { | ||||||
|  | 
 | ||||||
|  |     @Bean | ||||||
|  |     public RestTemplate restTemplate() { | ||||||
|  |         RestTemplate restTemplate = new RestTemplate(); | ||||||
|  | 
 | ||||||
|  |         List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors(); | ||||||
|  |         if (CollectionUtils.isEmpty(interceptors)) { | ||||||
|  |             interceptors = new ArrayList<ClientHttpRequestInterceptor>(); | ||||||
|  |         } | ||||||
|  |         interceptors.add(new RestTemplateHeaderModifierInterceptor()); | ||||||
|  |         restTemplate.setInterceptors(interceptors); | ||||||
|  |         return restTemplate; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | package com.baeldung.sampleapp.config; | ||||||
|  | 
 | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.springframework.context.annotation.ComponentScan; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.http.converter.HttpMessageConverter; | ||||||
|  | import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; | ||||||
|  | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | ||||||
|  | import org.springframework.web.servlet.config.annotation.EnableWebMvc; | ||||||
|  | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Please note that main web configuration is in src/main/webapp/WEB-INF/api-servlet.xml | ||||||
|  |  */ | ||||||
|  | @Configuration | ||||||
|  | @EnableWebMvc | ||||||
|  | @ComponentScan({ "com.baeldung.sampleapp.web" }) | ||||||
|  | public class WebConfig implements WebMvcConfigurer { | ||||||
|  | 
 | ||||||
|  |     public WebConfig() { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* | ||||||
|  |     @Override | ||||||
|  |     public void configureMessageConverters(final List<HttpMessageConverter<?>> messageConverters) { | ||||||
|  |         final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); | ||||||
|  |         builder.indentOutput(true) | ||||||
|  |             .dateFormat(new SimpleDateFormat("dd-MM-yyyy hh:mm")); | ||||||
|  |         messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build())); | ||||||
|  |         // messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); | ||||||
|  | 
 | ||||||
|  |         // messageConverters.add(new MappingJackson2HttpMessageConverter()); | ||||||
|  |      | ||||||
|  |         // messageConverters.add(new ProtobufHttpMessageConverter()); | ||||||
|  |      | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     */ | ||||||
|  | } | ||||||
| @ -0,0 +1,18 @@ | |||||||
|  | package com.baeldung.sampleapp.interceptors; | ||||||
|  | 
 | ||||||
|  | import java.io.IOException; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.HttpRequest; | ||||||
|  | import org.springframework.http.client.ClientHttpRequestExecution; | ||||||
|  | import org.springframework.http.client.ClientHttpRequestInterceptor; | ||||||
|  | import org.springframework.http.client.ClientHttpResponse; | ||||||
|  | 
 | ||||||
|  | public class RestTemplateHeaderModifierInterceptor implements ClientHttpRequestInterceptor { | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { | ||||||
|  |         ClientHttpResponse response = execution.execute(request, body);  | ||||||
|  |         response.getHeaders().add("Foo", "bar"); | ||||||
|  |         return response; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | package com.baeldung.sampleapp.repository; | ||||||
|  | 
 | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.web.dto.HeavyResource; | ||||||
|  | import com.baeldung.sampleapp.web.dto.HeavyResourceAddressOnly; | ||||||
|  | 
 | ||||||
|  | public class HeavyResourceRepository { | ||||||
|  | 
 | ||||||
|  |     public void save(HeavyResource heavyResource) { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void save(HeavyResourceAddressOnly partialUpdate) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void save(Map<String, Object> updates, String id) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void save(HeavyResource heavyResource, String id) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void save(HeavyResourceAddressOnly partialUpdate, String id) { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,47 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | import org.springframework.stereotype.Controller; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestParam; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseBody; | ||||||
|  | 
 | ||||||
|  | @Controller | ||||||
|  | @RequestMapping(value = "/ex") | ||||||
|  | public class BarMappingExamplesController { | ||||||
|  | 
 | ||||||
|  |     public BarMappingExamplesController() { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // API | ||||||
|  | 
 | ||||||
|  |     // with @RequestParam | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/bars") | ||||||
|  |     @ResponseBody | ||||||
|  |     public String getBarBySimplePathWithRequestParam(@RequestParam("id") final long id) { | ||||||
|  |         return "Get a specific Bar with id=" + id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/bars", params = "id") | ||||||
|  |     @ResponseBody | ||||||
|  |     public String getBarBySimplePathWithExplicitRequestParam(@RequestParam("id") final long id) { | ||||||
|  |         return "Get a specific Bar with id=" + id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/bars", params = { "id", "second" }) | ||||||
|  |     @ResponseBody | ||||||
|  |     public String getBarBySimplePathWithExplicitRequestParams(@RequestParam("id") final long id) { | ||||||
|  |         return "Get a specific Bar with id=" + id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // with @PathVariable | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/bars/{numericId:[\\d]+}") | ||||||
|  |     @ResponseBody | ||||||
|  |     public String getBarsBySimplePathWithPathVariable(@PathVariable final long numericId) { | ||||||
|  |         return "Get a specific Bar with id=" + numericId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.web.dto.Company; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | public class CompanyController { | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/companyRest", produces = MediaType.APPLICATION_JSON_VALUE) | ||||||
|  |     public Company getCompanyRest() { | ||||||
|  |         final Company company = new Company(1, "Xpto"); | ||||||
|  |         return company; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,85 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | import java.util.concurrent.CompletableFuture; | ||||||
|  | import java.util.function.Consumer; | ||||||
|  | 
 | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.ui.Model; | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | import org.springframework.web.context.request.async.DeferredResult; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | public class DeferredResultController { | ||||||
|  | 
 | ||||||
|  |     private final static Logger LOG = LoggerFactory.getLogger(DeferredResultController.class); | ||||||
|  | 
 | ||||||
|  |     @GetMapping("/async-deferredresult") | ||||||
|  |     public DeferredResult<ResponseEntity<?>> handleReqDefResult(Model model) { | ||||||
|  |         LOG.info("Received request"); | ||||||
|  |         DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>(); | ||||||
|  | 
 | ||||||
|  |         deferredResult.onCompletion(() -> LOG.info("Processing complete")); | ||||||
|  | 
 | ||||||
|  |         CompletableFuture.supplyAsync(() -> { | ||||||
|  |             LOG.info("Processing in separate thread"); | ||||||
|  |             try { | ||||||
|  |                 Thread.sleep(6000); | ||||||
|  |             } catch (InterruptedException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |             } | ||||||
|  |             return "OK"; | ||||||
|  |         }) | ||||||
|  |             .whenCompleteAsync((result, exc) -> deferredResult.setResult(ResponseEntity.ok(result))); | ||||||
|  | 
 | ||||||
|  |         LOG.info("Servlet thread freed"); | ||||||
|  |         return deferredResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @GetMapping("/process-blocking") | ||||||
|  |     public ResponseEntity<?> handleReqSync(Model model) { | ||||||
|  |         // ... | ||||||
|  |         return ResponseEntity.ok("ok"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @GetMapping("/async-deferredresult-timeout") | ||||||
|  |     public DeferredResult<ResponseEntity<?>> handleReqWithTimeouts(Model model) { | ||||||
|  |         LOG.info("Received async request with a configured timeout"); | ||||||
|  |         DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>(500l); | ||||||
|  |         deferredResult.onTimeout(() -> deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT) | ||||||
|  |             .body("Request timeout occurred."))); | ||||||
|  | 
 | ||||||
|  |         CompletableFuture.supplyAsync(() -> { | ||||||
|  |             LOG.info("Processing in separate thread"); | ||||||
|  |             try { | ||||||
|  |                 Thread.sleep(6000); | ||||||
|  |             } catch (InterruptedException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |             } | ||||||
|  |             return "error"; | ||||||
|  |         }) | ||||||
|  |             .whenCompleteAsync((result, exc) -> deferredResult.setResult(ResponseEntity.ok(result))); | ||||||
|  |         LOG.info("servlet thread freed"); | ||||||
|  |         return deferredResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @GetMapping("/async-deferredresult-error") | ||||||
|  |     public DeferredResult<ResponseEntity<?>> handleAsyncFailedRequest(Model model) { | ||||||
|  |         LOG.info("Received async request with a configured error handler"); | ||||||
|  |         DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>(); | ||||||
|  |         deferredResult.onError(new Consumer<Throwable>() { | ||||||
|  |             @Override | ||||||
|  |             public void accept(Throwable t) { | ||||||
|  |                 deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) | ||||||
|  |                     .body("An error occurred.")); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }); | ||||||
|  |         LOG.info("servlet thread freed"); | ||||||
|  |         return deferredResult; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMethod; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.repository.HeavyResourceRepository; | ||||||
|  | import com.baeldung.sampleapp.web.dto.HeavyResource; | ||||||
|  | import com.baeldung.sampleapp.web.dto.HeavyResourceAddressOnly; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | public class HeavyResourceController { | ||||||
|  | 
 | ||||||
|  |     private HeavyResourceRepository heavyResourceRepository = new HeavyResourceRepository(); | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/heavyresource/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) | ||||||
|  |     public ResponseEntity<?> saveResource(@RequestBody HeavyResource heavyResource, @PathVariable("id") String id) { | ||||||
|  |         heavyResourceRepository.save(heavyResource, id); | ||||||
|  |         return ResponseEntity.ok("resource saved"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/heavyresource/{id}", method = RequestMethod.PATCH, consumes = MediaType.APPLICATION_JSON_VALUE) | ||||||
|  |     public ResponseEntity<?> partialUpdateName(@RequestBody HeavyResourceAddressOnly partialUpdate, @PathVariable("id") String id) { | ||||||
|  |         heavyResourceRepository.save(partialUpdate, id); | ||||||
|  |         return ResponseEntity.ok("resource address updated"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/heavyresource2/{id}", method = RequestMethod.PATCH, consumes = MediaType.APPLICATION_JSON_VALUE) | ||||||
|  |     public ResponseEntity<?> partialUpdateGeneric(@RequestBody Map<String, Object> updates, | ||||||
|  |                                                   @PathVariable("id") String id) { | ||||||
|  |         heavyResourceRepository.save(updates, id); | ||||||
|  |         return ResponseEntity.ok("resource updated"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,39 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | import java.util.Date; | ||||||
|  | 
 | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.web.dto.Item; | ||||||
|  | import com.baeldung.sampleapp.web.dto.ItemManager; | ||||||
|  | import com.baeldung.sampleapp.web.dto.Views; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonView; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | public class ItemController { | ||||||
|  | 
 | ||||||
|  |     @JsonView(Views.Public.class) | ||||||
|  |     @RequestMapping("/items/{id}") | ||||||
|  |     public Item getItemPublic(@PathVariable final int id) { | ||||||
|  |         return ItemManager.getById(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @JsonView(Views.Internal.class) | ||||||
|  |     @RequestMapping("/items/internal/{id}") | ||||||
|  |     public Item getItemInternal(@PathVariable final int id) { | ||||||
|  |         return ItemManager.getById(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/date") | ||||||
|  |     public Date getCurrentDate() throws Exception { | ||||||
|  |         return new Date(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping("/delay/{seconds}") | ||||||
|  |     public void getCurrentTime(@PathVariable final int seconds) throws Exception { | ||||||
|  | 
 | ||||||
|  |         Thread.sleep(seconds * 1000); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,85 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | import javax.servlet.http.HttpServletResponse; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Controller; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMethod; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseBody; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseStatus; | ||||||
|  | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.web.dto.Foo; | ||||||
|  | import com.baeldung.sampleapp.web.exception.ResourceNotFoundException; | ||||||
|  | 
 | ||||||
|  | @Controller | ||||||
|  | @RequestMapping(value = "/foos") | ||||||
|  | public class MyFooController { | ||||||
|  | 
 | ||||||
|  |     private final Map<Long, Foo> myfoos; | ||||||
|  | 
 | ||||||
|  |     public MyFooController() { | ||||||
|  |         super(); | ||||||
|  |         myfoos = new HashMap<Long, Foo>(); | ||||||
|  |         myfoos.put(1L, new Foo(1L, "sample foo")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // API - read | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.GET, produces = { "application/json" }) | ||||||
|  |     @ResponseBody | ||||||
|  |     public Collection<Foo> findAll() { | ||||||
|  |         return myfoos.values(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = { "application/json" }) | ||||||
|  |     @ResponseBody | ||||||
|  |     public Foo findById(@PathVariable final long id) { | ||||||
|  |         final Foo foo = myfoos.get(id); | ||||||
|  |         if (foo == null) { | ||||||
|  |             throw new ResourceNotFoundException(); | ||||||
|  |         } | ||||||
|  |         return foo; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // API - write | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.PUT, value = "/{id}") | ||||||
|  |     @ResponseStatus(HttpStatus.OK) | ||||||
|  |     @ResponseBody | ||||||
|  |     public Foo updateFoo(@PathVariable("id") final long id, @RequestBody final Foo foo) { | ||||||
|  |         myfoos.put(id, foo); | ||||||
|  |         return foo; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.PATCH, value = "/{id}") | ||||||
|  |     @ResponseStatus(HttpStatus.OK) | ||||||
|  |     public void updateFoo2(@PathVariable("id") final long id, @RequestBody final Foo foo) { | ||||||
|  |         myfoos.put(id, foo); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.POST) | ||||||
|  |     @ResponseStatus(HttpStatus.CREATED) | ||||||
|  |     @ResponseBody | ||||||
|  |     public Foo createFoo(@RequestBody final Foo foo, HttpServletResponse response) { | ||||||
|  |         myfoos.put(foo.getId(), foo); | ||||||
|  |         response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentRequest() | ||||||
|  |             .path("/" + foo.getId()) | ||||||
|  |             .toUriString()); | ||||||
|  |         return foo; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") | ||||||
|  |     @ResponseStatus(HttpStatus.OK) | ||||||
|  |     public void deleteById(@PathVariable final long id) { | ||||||
|  |         myfoos.remove(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.PostMapping; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseBody; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseStatus; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.web.dto.PactDto; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | public class PactController { | ||||||
|  | 
 | ||||||
|  |     List<PactDto> pacts = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  |     @GetMapping(value = "/pact", produces = MediaType.APPLICATION_JSON_VALUE) | ||||||
|  |     @ResponseBody | ||||||
|  |     public PactDto getPact() { | ||||||
|  |         return new PactDto(true, "tom"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @PostMapping("/pact") | ||||||
|  |     @ResponseStatus(HttpStatus.CREATED) | ||||||
|  |     public void createPact(PactDto pact) { | ||||||
|  |         pacts.add(pact); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,74 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller; | ||||||
|  | 
 | ||||||
|  | import java.io.BufferedOutputStream; | ||||||
|  | import java.io.File; | ||||||
|  | import java.io.FileOutputStream; | ||||||
|  | import java.text.DateFormat; | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | import java.util.Date; | ||||||
|  | 
 | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMethod; | ||||||
|  | import org.springframework.web.bind.annotation.RequestParam; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | import org.springframework.web.multipart.MultipartFile; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.web.dto.Foo; | ||||||
|  | 
 | ||||||
|  | // used to test HttpClientPostingTest | ||||||
|  | @RestController | ||||||
|  | public class SimplePostController { | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/users", method = RequestMethod.POST) | ||||||
|  |     public String postUser(@RequestParam final String username, @RequestParam final String password) { | ||||||
|  |         return "Success" + username; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/users/detail", method = RequestMethod.POST) | ||||||
|  |     public String postUserDetail(@RequestBody final Foo entity) { | ||||||
|  |         return "Success" + entity.getId(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/users/multipart", method = RequestMethod.POST) | ||||||
|  |     public String uploadFile(@RequestParam final String username, @RequestParam final String password, @RequestParam("file") final MultipartFile file) { | ||||||
|  |         if (!file.isEmpty()) { | ||||||
|  |             try { | ||||||
|  |                 final DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH.mm.ss"); | ||||||
|  |                 final String fileName = dateFormat.format(new Date()); | ||||||
|  |                 final File fileServer = new File(fileName); | ||||||
|  |                 fileServer.createNewFile(); | ||||||
|  |                 final byte[] bytes = file.getBytes(); | ||||||
|  |                 final BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileServer)); | ||||||
|  |                 stream.write(bytes); | ||||||
|  |                 stream.close(); | ||||||
|  |                 return "You successfully uploaded " + username; | ||||||
|  |             } catch (final Exception e) { | ||||||
|  |                 return "You failed to upload " + e.getMessage(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             return "You failed to upload because the file was empty."; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/users/upload", method = RequestMethod.POST) | ||||||
|  |     public String postMultipart(@RequestParam("file") final MultipartFile file) { | ||||||
|  |         if (!file.isEmpty()) { | ||||||
|  |             try { | ||||||
|  |                 final DateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH.mm.ss"); | ||||||
|  |                 final String fileName = dateFormat.format(new Date()); | ||||||
|  |                 final File fileServer = new File(fileName); | ||||||
|  |                 fileServer.createNewFile(); | ||||||
|  |                 final byte[] bytes = file.getBytes(); | ||||||
|  |                 final BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileServer)); | ||||||
|  |                 stream.write(bytes); | ||||||
|  |                 stream.close(); | ||||||
|  |                 return "You successfully uploaded "; | ||||||
|  |             } catch (final Exception e) { | ||||||
|  |                 return "You failed to upload " + e.getMessage(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             return "You failed to upload because the file was empty."; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller.mediatypes; | ||||||
|  | 
 | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMethod; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseBody; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.sampleapp.web.dto.BaeldungItem; | ||||||
|  | import com.baeldung.sampleapp.web.dto.BaeldungItemV2; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | @RequestMapping(value = "/", produces = "application/vnd.baeldung.api.v1+json") | ||||||
|  | public class CustomMediaTypeController { | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.GET, value = "/public/api/items/{id}", produces = "application/vnd.baeldung.api.v1+json") | ||||||
|  |     public @ResponseBody BaeldungItem getItem(@PathVariable("id") String id) { | ||||||
|  |         return new BaeldungItem("itemId1"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(method = RequestMethod.GET, value = "/public/api/items/{id}", produces = "application/vnd.baeldung.api.v2+json") | ||||||
|  |     public @ResponseBody BaeldungItemV2 getItemSecondAPIVersion(@PathVariable("id") String id) { | ||||||
|  |         return new BaeldungItemV2("itemName"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,68 @@ | |||||||
|  | package com.baeldung.sampleapp.web.controller.redirect; | ||||||
|  | 
 | ||||||
|  | import javax.servlet.http.HttpServletRequest; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.stereotype.Controller; | ||||||
|  | import org.springframework.ui.ModelMap; | ||||||
|  | import org.springframework.web.bind.annotation.ModelAttribute; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMethod; | ||||||
|  | import org.springframework.web.servlet.ModelAndView; | ||||||
|  | import org.springframework.web.servlet.View; | ||||||
|  | import org.springframework.web.servlet.mvc.support.RedirectAttributes; | ||||||
|  | import org.springframework.web.servlet.view.RedirectView; | ||||||
|  | 
 | ||||||
|  | @Controller | ||||||
|  | @RequestMapping("/") | ||||||
|  | public class RedirectController { | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/redirectWithXMLConfig", method = RequestMethod.GET) | ||||||
|  |     public ModelAndView redirectWithUsingXMLConfig(final ModelMap model) { | ||||||
|  |         model.addAttribute("attribute", "redirectWithXMLConfig"); | ||||||
|  |         return new ModelAndView("RedirectedUrl", model); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/redirectWithRedirectPrefix", method = RequestMethod.GET) | ||||||
|  |     public ModelAndView redirectWithUsingRedirectPrefix(final ModelMap model) { | ||||||
|  |         model.addAttribute("attribute", "redirectWithRedirectPrefix"); | ||||||
|  |         return new ModelAndView("redirect:/redirectedUrl", model); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/redirectWithRedirectAttributes", method = RequestMethod.GET) | ||||||
|  |     public RedirectView redirectWithRedirectAttributes(final RedirectAttributes redirectAttributes) { | ||||||
|  |         redirectAttributes.addFlashAttribute("flashAttribute", "redirectWithRedirectAttributes"); | ||||||
|  |         redirectAttributes.addAttribute("attribute", "redirectWithRedirectAttributes"); | ||||||
|  |         return new RedirectView("redirectedUrl"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/redirectWithRedirectView", method = RequestMethod.GET) | ||||||
|  |     public RedirectView redirectWithUsingRedirectView(final ModelMap model) { | ||||||
|  |         model.addAttribute("attribute", "redirectWithRedirectView"); | ||||||
|  |         return new RedirectView("redirectedUrl"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/forwardWithForwardPrefix", method = RequestMethod.GET) | ||||||
|  |     public ModelAndView forwardWithUsingForwardPrefix(final ModelMap model) { | ||||||
|  |         model.addAttribute("attribute", "redirectWithForwardPrefix"); | ||||||
|  |         return new ModelAndView("forward:/redirectedUrl", model); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/redirectedUrl", method = RequestMethod.GET) | ||||||
|  |     public ModelAndView redirection(final ModelMap model, @ModelAttribute("flashAttribute") final Object flashAttribute) { | ||||||
|  |         model.addAttribute("redirectionAttribute", flashAttribute); | ||||||
|  |         return new ModelAndView("redirection", model); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/redirectPostToPost", method = RequestMethod.POST) | ||||||
|  |     public ModelAndView redirectPostToPost(HttpServletRequest request) { | ||||||
|  |         request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT); | ||||||
|  |         return new ModelAndView("redirect:/redirectedPostToPost"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @RequestMapping(value = "/redirectedPostToPost", method = RequestMethod.POST) | ||||||
|  |     public ModelAndView redirectedPostToPost() { | ||||||
|  |         return new ModelAndView("redirection"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | public class BaeldungItem { | ||||||
|  |     private final String itemId; | ||||||
|  | 
 | ||||||
|  |     public BaeldungItem(String itemId) { | ||||||
|  |         this.itemId = itemId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getItemId() { | ||||||
|  |         return itemId; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | public class BaeldungItemV2 { | ||||||
|  |     private final String itemName; | ||||||
|  | 
 | ||||||
|  |     public BaeldungItemV2(String itemName) { | ||||||
|  |         this.itemName = itemName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getItemName() { | ||||||
|  |         return itemName; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | public class Company { | ||||||
|  | 
 | ||||||
|  |     private long id; | ||||||
|  |     private String name; | ||||||
|  | 
 | ||||||
|  |     public Company() { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Company(final long id, final String name) { | ||||||
|  |         this.id = id; | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(final String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(final long id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "Company [id=" + id + ", name=" + name + "]"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | public class Foo { | ||||||
|  |     private long id; | ||||||
|  |     private String name; | ||||||
|  | 
 | ||||||
|  |     public Foo() { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Foo(final String name) { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Foo(final long id, final String name) { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         this.id = id; | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // API | ||||||
|  | 
 | ||||||
|  |     public long getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(final long id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(final String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,62 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | public class HeavyResource { | ||||||
|  |     private Integer id; | ||||||
|  |     private String name; | ||||||
|  |     private String surname; | ||||||
|  |     private Integer age; | ||||||
|  |     private String address; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public HeavyResource() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public HeavyResource(Integer id, String name, String surname, Integer age, String address) { | ||||||
|  |         this.id = id; | ||||||
|  |         this.name = name; | ||||||
|  |         this.surname = surname; | ||||||
|  |         this.age = age; | ||||||
|  |         this.address = address; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Integer getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(Integer id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getSurname() { | ||||||
|  |         return surname; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSurname(String surname) { | ||||||
|  |         this.surname = surname; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Integer getAge() { | ||||||
|  |         return age; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setAge(Integer age) { | ||||||
|  |         this.age = age; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getAddress() { | ||||||
|  |         return address; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setAddress(String address) { | ||||||
|  |         this.address = address; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | public class HeavyResourceAddressOnly { | ||||||
|  |     private Integer id; | ||||||
|  |     private String address; | ||||||
|  | 
 | ||||||
|  |     public HeavyResourceAddressOnly() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public HeavyResourceAddressOnly(Integer id, String address) { | ||||||
|  |         this.id = id; | ||||||
|  |         this.address = address; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Integer getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(Integer id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getAddress() { | ||||||
|  |         return address; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setAddress(String address) { | ||||||
|  |         this.address = address; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | public class HeavyResourceAddressPartialUpdate { | ||||||
|  |     private Integer id; | ||||||
|  |     private String address; | ||||||
|  | 
 | ||||||
|  |     public HeavyResourceAddressPartialUpdate() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public HeavyResourceAddressPartialUpdate(Integer id, String address) { | ||||||
|  |         this.id = id; | ||||||
|  |         this.address = address; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Integer getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(Integer id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getAddress() { | ||||||
|  |         return address; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setAddress(String address) { | ||||||
|  |         this.address = address; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | import com.fasterxml.jackson.annotation.JsonView; | ||||||
|  | 
 | ||||||
|  | public class Item { | ||||||
|  |     @JsonView(Views.Public.class) | ||||||
|  |     public int id; | ||||||
|  | 
 | ||||||
|  |     @JsonView(Views.Public.class) | ||||||
|  |     public String itemName; | ||||||
|  | 
 | ||||||
|  |     @JsonView(Views.Internal.class) | ||||||
|  |     public String ownerName; | ||||||
|  | 
 | ||||||
|  |     public Item() { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Item(final int id, final String itemName, final String ownerName) { | ||||||
|  |         this.id = id; | ||||||
|  |         this.itemName = itemName; | ||||||
|  |         this.ownerName = ownerName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getItemName() { | ||||||
|  |         return itemName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getOwnerName() { | ||||||
|  |         return ownerName; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | public class ItemManager { | ||||||
|  | 
 | ||||||
|  |     public static Item getById(final int id) { | ||||||
|  |         final Item item = new Item(2, "book", "John"); | ||||||
|  |         return item; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | public class PactDto { | ||||||
|  | 
 | ||||||
|  |     private boolean condition; | ||||||
|  |     private String name; | ||||||
|  | 
 | ||||||
|  |     public PactDto() { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public PactDto(boolean condition, String name) { | ||||||
|  |         super(); | ||||||
|  |         this.condition = condition; | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isCondition() { | ||||||
|  |         return condition; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setCondition(boolean condition) { | ||||||
|  |         this.condition = condition; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | package com.baeldung.sampleapp.web.dto; | ||||||
|  | 
 | ||||||
|  | public class Views { | ||||||
|  |     public static class Public { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static class Internal extends Public { | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | package com.baeldung.sampleapp.web.exception; | ||||||
|  | 
 | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.web.bind.annotation.ResponseStatus; | ||||||
|  | 
 | ||||||
|  | @ResponseStatus(value = HttpStatus.NOT_FOUND) | ||||||
|  | public class ResourceNotFoundException extends RuntimeException { | ||||||
|  | } | ||||||
| @ -11,6 +11,7 @@ import org.springframework.context.annotation.ComponentScan; | |||||||
| import org.springframework.web.context.ContextLoaderListener; | import org.springframework.web.context.ContextLoaderListener; | ||||||
| import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; | ||||||
| import org.springframework.web.servlet.DispatcherServlet; | import org.springframework.web.servlet.DispatcherServlet; | ||||||
|  | import org.springframework.context.annotation.PropertySource; | ||||||
| 
 | 
 | ||||||
| import com.baeldung.web.log.config.CustomeRequestLoggingFilter; | import com.baeldung.web.log.config.CustomeRequestLoggingFilter; | ||||||
| 
 | 
 | ||||||
| @ -18,6 +19,7 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer | |||||||
| 
 | 
 | ||||||
| @EnableAutoConfiguration | @EnableAutoConfiguration | ||||||
| @ComponentScan("com.baeldung.web.log") | @ComponentScan("com.baeldung.web.log") | ||||||
|  | @PropertySource("application-log.properties") | ||||||
| @SpringBootApplication | @SpringBootApplication | ||||||
| public class Application extends SpringBootServletInitializer { | public class Application extends SpringBootServletInitializer { | ||||||
| 
 | 
 | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | server.port=8082 | ||||||
|  | server.servlet.context-path=/spring-rest | ||||||
| @ -20,3 +20,4 @@ spring.application.name=spring-boot-management | |||||||
| server.port=8081 | server.port=8081 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -7,14 +7,17 @@ import org.junit.Test; | |||||||
| import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||||
| import org.springframework.boot.test.context.SpringBootTest; | import org.springframework.boot.test.context.SpringBootTest; | ||||||
| import org.springframework.boot.test.web.client.TestRestTemplate; | import org.springframework.boot.test.web.client.TestRestTemplate; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
| import org.springframework.boot.web.server.LocalServerPort; | import org.springframework.boot.web.server.LocalServerPort; | ||||||
| import org.springframework.test.context.junit4.SpringRunner; | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||||||
|  | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | ||||||
| 
 | 
 | ||||||
| import com.baeldung.web.log.app.Application; | import com.baeldung.web.log.app.Application; | ||||||
| import com.baeldung.web.log.data.TaxiRide; | import com.baeldung.web.log.data.TaxiRide; | ||||||
| 
 | 
 | ||||||
| @RunWith(SpringRunner.class) | @RunWith(SpringRunner.class) | ||||||
| @SpringBootTest(classes = { Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | @SpringBootTest(classes = { Application.class, TaxiFareControllerIntegrationTest.SecurityConfig.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) | ||||||
| public class TaxiFareControllerIntegrationTest { | public class TaxiFareControllerIntegrationTest { | ||||||
|      |      | ||||||
|     @LocalServerPort |     @LocalServerPort | ||||||
| @ -23,6 +26,7 @@ public class TaxiFareControllerIntegrationTest { | |||||||
|     @Test |     @Test | ||||||
|     public void givenRequest_whenFetchTaxiFareRateCard_thanOK() { |     public void givenRequest_whenFetchTaxiFareRateCard_thanOK() { | ||||||
| 
 | 
 | ||||||
|  |         System.out.println(port); | ||||||
|         String URL = "http://localhost:" + port + "/spring-rest"; |         String URL = "http://localhost:" + port + "/spring-rest"; | ||||||
|         TestRestTemplate testRestTemplate = new TestRestTemplate(); |         TestRestTemplate testRestTemplate = new TestRestTemplate(); | ||||||
|         TaxiRide taxiRide = new TaxiRide(true, 10l); |         TaxiRide taxiRide = new TaxiRide(true, 10l); | ||||||
| @ -32,4 +36,17 @@ public class TaxiFareControllerIntegrationTest { | |||||||
|        |        | ||||||
|         assertThat(fare, equalTo("200")); |         assertThat(fare, equalTo("200")); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Configuration | ||||||
|  |     static class SecurityConfig extends WebSecurityConfigurerAdapter { | ||||||
|  |         @Override | ||||||
|  |         protected void configure(HttpSecurity http) throws Exception { | ||||||
|  |             System.out.println("security being set"); | ||||||
|  |             http | ||||||
|  |                     .authorizeRequests() | ||||||
|  |                     .anyRequest().permitAll() | ||||||
|  |                     .and() | ||||||
|  |                     .csrf().disable(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -10,7 +10,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com | |||||||
| 
 | 
 | ||||||
| ### Relevant Articles:  | ### Relevant Articles:  | ||||||
| - [Integration Testing with the Maven Cargo plugin](https://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin) | - [Integration Testing with the Maven Cargo plugin](https://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin) | ||||||
| - [Project Configuration with Spring](https://www.baeldung.com/project-configuration-with-spring) |  | ||||||
| - [Metrics for your Spring REST API](https://www.baeldung.com/spring-rest-api-metrics) | - [Metrics for your Spring REST API](https://www.baeldung.com/spring-rest-api-metrics) | ||||||
| 
 | 
 | ||||||
| ### Build the Project | ### Build the Project | ||||||
|  | |||||||
| @ -9,5 +9,4 @@ This module contains articles about REST APIs in Spring | |||||||
| - [Spring RequestMapping](https://www.baeldung.com/spring-requestmapping) | - [Spring RequestMapping](https://www.baeldung.com/spring-requestmapping) | ||||||
| - [Spring and Apache FileUpload](https://www.baeldung.com/spring-apache-file-upload) | - [Spring and Apache FileUpload](https://www.baeldung.com/spring-apache-file-upload) | ||||||
| - [Test a REST API with curl](https://www.baeldung.com/curl-rest) | - [Test a REST API with curl](https://www.baeldung.com/curl-rest) | ||||||
| - [CORS with Spring](https://www.baeldung.com/spring-cors) |  | ||||||
| - [Best Practices for REST API Error Handling](https://www.baeldung.com/rest-api-error-handling-best-practices) | - [Best Practices for REST API Error Handling](https://www.baeldung.com/rest-api-error-handling-best-practices) | ||||||
							
								
								
									
										2
									
								
								spring-rest/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								spring-rest/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -4,7 +4,7 @@ | |||||||
| /target | /target | ||||||
| /neoDb* | /neoDb* | ||||||
| /data | /data | ||||||
| /src/main/webapp/WEB-INF/classes | /spring-boot-runtime/src/main/webapp/WEB-INF/classes | ||||||
| */META-INF/* | */META-INF/* | ||||||
| 
 | 
 | ||||||
| # Packaged files # | # Packaged files # | ||||||
|  | |||||||
| @ -12,9 +12,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring | |||||||
| - [Guide to UriComponentsBuilder in Spring](https://www.baeldung.com/spring-uricomponentsbuilder) | - [Guide to UriComponentsBuilder in Spring](https://www.baeldung.com/spring-uricomponentsbuilder) | ||||||
| - [A Custom Media Type for a Spring REST API](https://www.baeldung.com/spring-rest-custom-media-type) | - [A Custom Media Type for a Spring REST API](https://www.baeldung.com/spring-rest-custom-media-type) | ||||||
| - [HTTP PUT vs HTTP PATCH in a REST API](https://www.baeldung.com/http-put-patch-difference-spring) | - [HTTP PUT vs HTTP PATCH in a REST API](https://www.baeldung.com/http-put-patch-difference-spring) | ||||||
| - [Spring – Log Incoming Requests](https://www.baeldung.com/spring-http-logging) |  | ||||||
| - [How to Change the Default Port in Spring Boot](https://www.baeldung.com/spring-boot-change-port) |  | ||||||
| - [Guide to DeferredResult in Spring](https://www.baeldung.com/spring-deferred-result) | - [Guide to DeferredResult in Spring](https://www.baeldung.com/spring-deferred-result) | ||||||
| - [Spring Custom Property Editor](https://www.baeldung.com/spring-mvc-custom-property-editor) |  | ||||||
| - [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header) | - [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header) | ||||||
| - [Download an Image or a File with Spring MVC](https://www.baeldung.com/spring-controller-return-image-file) | - [Download an Image or a File with Spring MVC](https://www.baeldung.com/spring-controller-return-image-file) | ||||||
|  | |||||||
| @ -5,17 +5,13 @@ import org.junit.runner.RunWith; | |||||||
| import org.springframework.boot.test.context.SpringBootTest; | import org.springframework.boot.test.context.SpringBootTest; | ||||||
| import org.springframework.test.context.junit4.SpringRunner; | import org.springframework.test.context.junit4.SpringRunner; | ||||||
| 
 | 
 | ||||||
| import com.baeldung.changeport.CustomApplication; |  | ||||||
| import com.baeldung.produceimage.ImageApplication; | import com.baeldung.produceimage.ImageApplication; | ||||||
| import com.baeldung.propertyeditor.PropertyEditorApplication; |  | ||||||
| import com.baeldung.responseheaders.ResponseHeadersApplication; | import com.baeldung.responseheaders.ResponseHeadersApplication; | ||||||
| import com.baeldung.sampleapp.config.MainApplication; |  | ||||||
| import com.baeldung.web.log.app.Application; |  | ||||||
| 
 | 
 | ||||||
| @RunWith(SpringRunner.class) | @RunWith(SpringRunner.class) | ||||||
| @SpringBootTest(classes = { CustomApplication.class, ImageApplication.class, PropertyEditorApplication.class, | @SpringBootTest(classes = { ImageApplication.class, | ||||||
| 		ResponseHeadersApplication.class, Application.class, com.baeldung.web.upload.app.UploadApplication.class, | 		ResponseHeadersApplication.class, com.baeldung.web.upload.app.UploadApplication.class, | ||||||
| 		MainApplication.class}) | 		}) | ||||||
| public class SpringContextIntegrationTest { | public class SpringContextIntegrationTest { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | |||||||
| @ -5,17 +5,14 @@ import org.junit.runner.RunWith; | |||||||
| import org.springframework.boot.test.context.SpringBootTest; | import org.springframework.boot.test.context.SpringBootTest; | ||||||
| import org.springframework.test.context.junit4.SpringRunner; | import org.springframework.test.context.junit4.SpringRunner; | ||||||
| 
 | 
 | ||||||
| import com.baeldung.changeport.CustomApplication; |  | ||||||
| import com.baeldung.produceimage.ImageApplication; | import com.baeldung.produceimage.ImageApplication; | ||||||
| import com.baeldung.propertyeditor.PropertyEditorApplication; |  | ||||||
| import com.baeldung.responseheaders.ResponseHeadersApplication; | import com.baeldung.responseheaders.ResponseHeadersApplication; | ||||||
| import com.baeldung.sampleapp.config.MainApplication; |  | ||||||
| import com.baeldung.web.log.app.Application; |  | ||||||
| 
 | 
 | ||||||
| @RunWith(SpringRunner.class) | @RunWith(SpringRunner.class) | ||||||
| @SpringBootTest(classes = { CustomApplication.class, ImageApplication.class, PropertyEditorApplication.class, | @SpringBootTest(classes = { ImageApplication.class, | ||||||
| 		ResponseHeadersApplication.class, Application.class, com.baeldung.web.upload.app.UploadApplication.class, | 		ResponseHeadersApplication.class, | ||||||
| 		MainApplication.class}) |         com.baeldung.web.upload.app.UploadApplication.class, | ||||||
|  | 		}) | ||||||
| public class SpringContextTest { | public class SpringContextTest { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user