JAVA-3520: Moved spring-mvc-basics-3 inside spring-web-modules
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
## Spring MVC Basics 3
|
||||
|
||||
This module contains articles about Spring MVC
|
||||
|
||||
## Relevant articles:
|
||||
- [How to Read HTTP Headers in Spring REST Controllers](https://www.baeldung.com/spring-rest-http-headers)
|
||||
- [A Custom Data Binder in Spring MVC](https://www.baeldung.com/spring-mvc-custom-data-binder)
|
||||
- [Validating Lists in a Spring Controller](https://www.baeldung.com/spring-validate-list-controller)
|
||||
- [Spring Validation Message Interpolation](https://www.baeldung.com/spring-validation-message-interpolation)
|
||||
- [Using a Slash Character in Spring URLs](https://www.baeldung.com/spring-slash-character-in-url)
|
||||
- [Using Enums as Request Parameters in Spring](https://www.baeldung.com/spring-enum-request-param)
|
||||
- [Excluding URLs for a Filter in a Spring Web Application](https://www.baeldung.com/spring-exclude-filter)
|
||||
- [Guide to Flash Attributes in a Spring Web Application](https://www.baeldung.com/spring-web-flash-attributes)
|
||||
- [Handling URL Encoded Form Data in Spring REST](https://www.baeldung.com/spring-url-encoded-form-data)
|
||||
- [Reading HttpServletRequest Multiple Times in Spring](https://www.baeldung.com/spring-reading-httpservletrequest-multiple-times)
|
||||
- More articles: [[<-- prev]](/spring-mvc-basics-2)[[more -->]](/spring-mvc-basics-4)
|
||||
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-mvc-basics-3</artifactId>
|
||||
<name>spring-mvc-basics-3</name>
|
||||
<packaging>war</packaging>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>javax.persistence-api</artifactId>
|
||||
<version>${jpa.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.subethamail</groupId>
|
||||
<artifactId>subethasmtp</artifactId>
|
||||
<version>${subethasmtp.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-context</artifactId>
|
||||
<version>${springcloud.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${httpclient.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>**/conf.properties</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>autoconfiguration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*IntTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/AutoconfigurationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<!-- The main class to start by executing java -jar -->
|
||||
<start-class>com.baeldung.boot.Application</start-class>
|
||||
<jquery.version>3.1.1</jquery.version>
|
||||
<bootstrap.version>3.3.7-1</bootstrap.version>
|
||||
<jpa.version>2.2</jpa.version>
|
||||
<guava.version>18.0</guava.version>
|
||||
<subethasmtp.version>3.1.7</subethasmtp.version>
|
||||
<springcloud.version>2.0.2.RELEASE</springcloud.version>
|
||||
<httpclient.version>4.5.8</httpclient.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.boot;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
public static void main(String[] args) {
|
||||
applicationContext = SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.boot.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.boot.converter.GenericBigDecimalConverter;
|
||||
import com.baeldung.boot.converter.StringToAbstractEntityConverterFactory;
|
||||
import com.baeldung.boot.converter.StringToEmployeeConverter;
|
||||
import com.baeldung.boot.converter.StringToEnumConverter;
|
||||
import com.baeldung.boot.web.resolver.HeaderVersionArgumentResolver;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new HeaderVersionArgumentResolver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFormatters(FormatterRegistry registry) {
|
||||
registry.addConverter(new StringToEmployeeConverter());
|
||||
registry.addConverter(new StringToEnumConverter());
|
||||
registry.addConverterFactory(new StringToAbstractEntityConverterFactory());
|
||||
registry.addConverter(new GenericBigDecimalConverter());
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.baeldung.boot.controller;
|
||||
|
||||
import com.baeldung.boot.domain.GenericEntity;
|
||||
import com.baeldung.boot.domain.Modes;
|
||||
import com.baeldung.boot.web.resolver.Version;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
public class GenericEntityController {
|
||||
private List<GenericEntity> entityList = new ArrayList<>();
|
||||
|
||||
{
|
||||
entityList.add(new GenericEntity(1l, "entity_1"));
|
||||
entityList.add(new GenericEntity(2l, "entity_2"));
|
||||
entityList.add(new GenericEntity(3l, "entity_3"));
|
||||
entityList.add(new GenericEntity(4l, "entity_4"));
|
||||
}
|
||||
|
||||
@GetMapping("/entity/all")
|
||||
public List<GenericEntity> findAll() {
|
||||
return entityList;
|
||||
}
|
||||
|
||||
@PostMapping("/entity")
|
||||
public GenericEntity addEntity(GenericEntity entity) {
|
||||
entityList.add(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@GetMapping("/entity/findby/{id}")
|
||||
public GenericEntity findById(@PathVariable Long id) {
|
||||
return entityList.stream().filter(entity -> entity.getId().equals(id)).findFirst().get();
|
||||
}
|
||||
|
||||
@GetMapping("/entity/findbydate/{date}")
|
||||
public GenericEntity findByDate(@PathVariable("date") LocalDateTime date) {
|
||||
return entityList.stream().findFirst().get();
|
||||
}
|
||||
|
||||
@GetMapping("/entity/findbymode/{mode}")
|
||||
public GenericEntity findByEnum(@PathVariable("mode") Modes mode) {
|
||||
return entityList.stream().findFirst().get();
|
||||
}
|
||||
|
||||
@GetMapping("/entity/findbyversion")
|
||||
public ResponseEntity findByVersion(@Version String version) {
|
||||
return version != null ? new ResponseEntity(entityList.stream().findFirst().get(), HttpStatus.OK) : new ResponseEntity(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.boot.converter;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
public class GenericBigDecimalConverter implements GenericConverter {
|
||||
@Override
|
||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
|
||||
ConvertiblePair[] pairs = new ConvertiblePair[] { new ConvertiblePair(Number.class, BigDecimal.class), new ConvertiblePair(String.class, BigDecimal.class) };
|
||||
|
||||
return ImmutableSet.copyOf(pairs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
if (sourceType.getType() == BigDecimal.class) {
|
||||
return source;
|
||||
}
|
||||
|
||||
if (sourceType.getType() == String.class) {
|
||||
String number = (String) source;
|
||||
return new BigDecimal(number);
|
||||
} else {
|
||||
Number number = (Number) source;
|
||||
BigDecimal converted = new BigDecimal(number.doubleValue());
|
||||
return converted.setScale(2, BigDecimal.ROUND_HALF_EVEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.baeldung.boot.converter;
|
||||
|
||||
import com.baeldung.boot.domain.AbstractEntity;
|
||||
import com.baeldung.boot.domain.Bar;
|
||||
import com.baeldung.boot.domain.Foo;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
|
||||
public class StringToAbstractEntityConverterFactory implements ConverterFactory<String, AbstractEntity>{
|
||||
|
||||
@Override
|
||||
public <T extends AbstractEntity> Converter<String, T> getConverter(Class<T> targetClass) {
|
||||
|
||||
return new StringToAbstractEntityConverter<>(targetClass);
|
||||
}
|
||||
|
||||
|
||||
private static class StringToAbstractEntityConverter<T extends AbstractEntity> implements Converter<String, T> {
|
||||
|
||||
private Class<T> targetClass;
|
||||
|
||||
public StringToAbstractEntityConverter(Class<T> targetClass) {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T convert(String source) {
|
||||
long id = Long.parseLong(source);
|
||||
if(this.targetClass == Foo.class) {
|
||||
return (T) new Foo(id);
|
||||
}
|
||||
else if(this.targetClass == Bar.class) {
|
||||
return (T) new Bar(id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.boot.converter;
|
||||
|
||||
import com.baeldung.boot.domain.Employee;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
public class StringToEmployeeConverter implements Converter<String, Employee> {
|
||||
|
||||
@Override
|
||||
public Employee convert(String from) {
|
||||
String[] data = from.split(",");
|
||||
return new Employee(Long.parseLong(data[0]), Double.parseDouble(data[1]));
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.boot.converter;
|
||||
|
||||
import com.baeldung.boot.domain.Modes;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
public class StringToEnumConverter implements Converter<String, Modes> {
|
||||
|
||||
@Override
|
||||
public Modes convert(String from) {
|
||||
return Modes.valueOf(from);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.boot.converter;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Component
|
||||
public class StringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {
|
||||
|
||||
@Override
|
||||
public LocalDateTime convert(final String source) {
|
||||
return LocalDateTime.parse(source, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.boot.converter.controller;
|
||||
|
||||
import com.baeldung.boot.domain.Bar;
|
||||
import com.baeldung.boot.domain.Foo;
|
||||
import com.baeldung.boot.domain.Modes;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/string-to-abstract")
|
||||
public class AbstractEntityController {
|
||||
|
||||
@GetMapping("/foo/{foo}")
|
||||
public ResponseEntity<Object> getStringToFoo(@PathVariable Foo foo) {
|
||||
return ResponseEntity.ok(foo);
|
||||
}
|
||||
|
||||
@GetMapping("/bar/{bar}")
|
||||
public ResponseEntity<Object> getStringToBar(@PathVariable Bar bar) {
|
||||
return ResponseEntity.ok(bar);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<Object> getStringToMode(@RequestParam("mode") Modes mode) {
|
||||
return ResponseEntity.ok(mode);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.boot.converter.controller;
|
||||
|
||||
import com.baeldung.boot.domain.Employee;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/string-to-employee")
|
||||
public class StringToEmployeeConverterController {
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<Object> getStringToEmployee(@RequestParam("employee") Employee employee) {
|
||||
return ResponseEntity.ok(employee);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
public abstract class AbstractEntity {
|
||||
|
||||
long id;
|
||||
public AbstractEntity(long id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
public class Bar extends AbstractEntity {
|
||||
|
||||
private int value;
|
||||
|
||||
public Bar(long id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Bar(long id, int value) {
|
||||
super(id);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Bar [value=" + value + ", id=" + id + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Employee {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
private double salary;
|
||||
|
||||
public Employee() {
|
||||
}
|
||||
|
||||
public Employee(long id, double salary) {
|
||||
this.id = id;
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public double getSalary() {
|
||||
return salary;
|
||||
}
|
||||
|
||||
public void setSalary(double salary) {
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric;
|
||||
public class Foo extends AbstractEntity {
|
||||
|
||||
private String name;
|
||||
|
||||
public Foo(long id) {
|
||||
super(id);
|
||||
name = randomAlphanumeric(4);
|
||||
}
|
||||
|
||||
public Foo(long id, String name) {
|
||||
super(id);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Foo [name=" + name + ", id=" + id + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class GenericEntity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
private String value;
|
||||
|
||||
public GenericEntity() {
|
||||
}
|
||||
|
||||
public GenericEntity(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public GenericEntity(Long id, String value) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.boot.domain;
|
||||
|
||||
public enum Modes {
|
||||
|
||||
ALPHA, BETA;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.baeldung.boot.repository;
|
||||
|
||||
import com.baeldung.boot.domain.GenericEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface GenericEntityRepository extends JpaRepository<GenericEntity, Long> {
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.boot.web.resolver;
|
||||
|
||||
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;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Component
|
||||
public class HeaderVersionArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(final MethodParameter methodParameter) {
|
||||
return methodParameter.getParameterAnnotation(Version.class) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(final MethodParameter methodParameter, final ModelAndViewContainer modelAndViewContainer, final NativeWebRequest nativeWebRequest, final WebDataBinderFactory webDataBinderFactory) throws Exception {
|
||||
HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
|
||||
|
||||
return request.getHeader("Version");
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.boot.web.resolver;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.PARAMETER)
|
||||
public @interface Version {
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.cachedrequest;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {
|
||||
|
||||
private byte[] cachedBody;
|
||||
|
||||
public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
|
||||
super(request);
|
||||
InputStream requestInputStream = request.getInputStream();
|
||||
this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
return new CachedBodyServletInputStream(this.cachedBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException {
|
||||
// Create a reader from cachedContent
|
||||
// and return it
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedBody);
|
||||
return new BufferedReader(new InputStreamReader(byteArrayInputStream));
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.cachedrequest;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
|
||||
public class CachedBodyServletInputStream extends ServletInputStream {
|
||||
|
||||
private InputStream cachedBodyInputStream;
|
||||
|
||||
public CachedBodyServletInputStream(byte[] cachedBody) {
|
||||
this.cachedBodyInputStream = new ByteArrayInputStream(cachedBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
try {
|
||||
return cachedBodyInputStream.available() == 0;
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return cachedBodyInputStream.read();
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.cachedrequest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
@Order(value = Ordered.HIGHEST_PRECEDENCE)
|
||||
@Component
|
||||
@WebFilter(filterName = "ContentCachingFilter", urlPatterns = "/*")
|
||||
public class ContentCachingFilter extends OncePerRequestFilter {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
|
||||
System.out.println("IN ContentCachingFilter ");
|
||||
CachedBodyHttpServletRequest cachedBodyHttpServletRequest = new CachedBodyHttpServletRequest(httpServletRequest);
|
||||
filterChain.doFilter(cachedBodyHttpServletRequest, httpServletResponse);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.cachedrequest;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
/**
|
||||
* To initialize the WebApplication, Please see
|
||||
* {@link com.baeldung.spring.config.MainWebAppInitializer}
|
||||
*/
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "com.baeldung.cachedrequest")
|
||||
public class HttpRequestDemoConfig implements WebMvcConfigurer {
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.baeldung.cachedrequest;
|
||||
|
||||
public class Person {
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private int age;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String firstName, String lastName, int age) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", age=" + age + '}';
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.cachedrequest;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class PersonController {
|
||||
|
||||
@PostMapping(value = "/person")
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void printPerson(@RequestBody Person person) {
|
||||
|
||||
System.out.println("In Demo Controller. Person " + "is : " + person);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/person")
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void getPerson() {
|
||||
|
||||
System.out.println("In Demo Controller get method.");
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.cachedrequest;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
@Component
|
||||
@WebFilter(filterName = "printRequestContentFilter", urlPatterns = "/*")
|
||||
public class PrintRequestContentFilter extends OncePerRequestFilter {
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
|
||||
System.out.println("IN PrintRequestContentFilter ");
|
||||
InputStream inputStream = httpServletRequest.getInputStream();
|
||||
byte[] body = StreamUtils.copyToByteArray(inputStream);
|
||||
System.out.println("In PrintRequestContentFilter. Request body is: " + new String(body));
|
||||
filterChain.doFilter(httpServletRequest, httpServletResponse);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.exclude_urls_filter;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@ComponentScan(basePackages = "com.baeldung.exclude_urls_filter")
|
||||
@Configuration
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.exclude_urls_filter.controller;
|
||||
|
||||
import com.baeldung.exclude_urls_filter.service.FAQService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class FAQController {
|
||||
|
||||
private final FAQService faqService;
|
||||
|
||||
@Autowired
|
||||
public FAQController(FAQService faqService) {
|
||||
this.faqService = faqService;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/faq/helpline", method = RequestMethod.GET)
|
||||
public ResponseEntity<String> getHelpLineNumber() {
|
||||
String helplineNumber = faqService.getHelpLineNumber();
|
||||
if (helplineNumber != null) {
|
||||
return new ResponseEntity<String>(helplineNumber, HttpStatus.OK);
|
||||
} else {
|
||||
return new ResponseEntity<String>("Unavailable", HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user