BAEL-7200
Modify Request Body Before Reaching Controller in Spring Boot
This commit is contained in:
		
							parent
							
								
									336ee922eb
								
							
						
					
					
						commit
						f90651c5f9
					
				| @ -49,6 +49,10 @@ | |||||||
|             <artifactId>commons-configuration</artifactId> |             <artifactId>commons-configuration</artifactId> | ||||||
|             <version>${commons-configuration.version}</version> |             <version>${commons-configuration.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.boot</groupId> | ||||||
|  |             <artifactId>spring-boot-starter-aop</artifactId> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <build> |     <build> | ||||||
| @ -61,6 +65,14 @@ | |||||||
|                     <layout>JAR</layout> |                     <layout>JAR</layout> | ||||||
|                 </configuration> |                 </configuration> | ||||||
|             </plugin> |             </plugin> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.apache.maven.plugins</groupId> | ||||||
|  |                 <artifactId>maven-compiler-plugin</artifactId> | ||||||
|  |                 <configuration> | ||||||
|  |                     <source>9</source> | ||||||
|  |                     <target>9</target> | ||||||
|  |                 </configuration> | ||||||
|  |             </plugin> | ||||||
|         </plugins> |         </plugins> | ||||||
|     </build> |     </build> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,11 @@ | |||||||
|  | package com.baeldung.modifyrequest; | ||||||
|  | 
 | ||||||
|  | import org.springframework.boot.SpringApplication; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | 
 | ||||||
|  | @SpringBootApplication(scanBasePackages = "com.baeldung.modifyrequest") | ||||||
|  | public class ModifyRequestApp { | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         SpringApplication.run(ModifyRequestApp.class, args); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,74 @@ | |||||||
|  | package com.baeldung.modifyrequest.aop; | ||||||
|  | 
 | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.context.annotation.Profile; | ||||||
|  | import org.springframework.core.MethodParameter; | ||||||
|  | import org.springframework.http.HttpHeaders; | ||||||
|  | import org.springframework.http.HttpInputMessage; | ||||||
|  | import org.springframework.http.converter.HttpMessageConverter; | ||||||
|  | import org.springframework.web.bind.annotation.RestControllerAdvice; | ||||||
|  | import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; | ||||||
|  | 
 | ||||||
|  | import java.io.*; | ||||||
|  | import java.lang.reflect.Type; | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
|  | 
 | ||||||
|  | @RestControllerAdvice | ||||||
|  | @Profile("aspectExample") | ||||||
|  | public class EscapeHtmlAspect implements RequestBodyAdvice { | ||||||
|  |     private static final Logger logger = LoggerFactory.getLogger(EscapeHtmlAspect.class); | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { | ||||||
|  |         //Apply this to all Controllers | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { | ||||||
|  |         logger.info("beforeBodyRead called"); | ||||||
|  |         InputStream inputStream = inputMessage.getBody(); | ||||||
|  |         return new HttpInputMessage() { | ||||||
|  |             @Override | ||||||
|  |             public InputStream getBody() throws IOException { | ||||||
|  |                 return new ByteArrayInputStream(escapeHtml(inputStream).getBytes(StandardCharsets.UTF_8)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public HttpHeaders getHeaders() { | ||||||
|  |                 return inputMessage.getHeaders(); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { | ||||||
|  |         // Return the modified object after reading the body | ||||||
|  |         return body; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { | ||||||
|  |         //return the original body | ||||||
|  |         return body; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private String escapeHtml(InputStream inputStream) throws IOException { | ||||||
|  |         StringBuilder stringBuilder = new StringBuilder(); | ||||||
|  |         BufferedReader bufferedReader = null; | ||||||
|  |         try (inputStream) { | ||||||
|  |             bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); | ||||||
|  |             char[] charBuffer = new char[128]; | ||||||
|  |             int bytesRead = -1; | ||||||
|  |             while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { | ||||||
|  |                 stringBuilder.append(charBuffer, 0, bytesRead); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         String input = stringBuilder.toString(); | ||||||
|  |         // Escape HTML characters | ||||||
|  |         return input.replaceAll("&", "&") | ||||||
|  |                 .replaceAll("<", "<") | ||||||
|  |                 .replaceAll(">", ">"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | package com.baeldung.modifyrequest.config; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.modifyrequest.interceptor.EscapeHtmlRequestInterceptor; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.context.annotation.Profile; | ||||||
|  | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | ||||||
|  | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||||||
|  | 
 | ||||||
|  | @Configuration | ||||||
|  | @Profile("interceptorExample") | ||||||
|  | public class WebMvcConfiguration implements WebMvcConfigurer { | ||||||
|  |     private static final Logger logger = LoggerFactory.getLogger(WebMvcConfiguration.class); | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void addInterceptors(InterceptorRegistry registry) { | ||||||
|  |         logger.info("addInterceptors() called"); | ||||||
|  |         registry.addInterceptor(new EscapeHtmlRequestInterceptor()) | ||||||
|  |                 .addPathPatterns("/save"); | ||||||
|  | 
 | ||||||
|  |         WebMvcConfigurer.super.addInterceptors(registry); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @ -0,0 +1,23 @@ | |||||||
|  | package com.baeldung.modifyrequest.controller; | ||||||
|  | 
 | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.web.bind.annotation.PostMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/") | ||||||
|  | public class UserController { | ||||||
|  |     Logger logger = LoggerFactory.getLogger(UserController.class); | ||||||
|  | 
 | ||||||
|  |     @PostMapping(value = "save") | ||||||
|  |     public ResponseEntity<String> saveUser(@RequestBody String user) { | ||||||
|  |         logger.info("save user info into database"); | ||||||
|  |         ResponseEntity<String> responseEntity = new ResponseEntity<>(user, HttpStatus.CREATED); | ||||||
|  |         return responseEntity; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | package com.baeldung.modifyrequest.filter; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.modifyrequest.requestwrapper.EscapeHtmlRequestWrapper; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.context.annotation.Profile; | ||||||
|  | import org.springframework.core.annotation.Order; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | import javax.servlet.*; | ||||||
|  | import javax.servlet.http.HttpServletRequest; | ||||||
|  | import java.io.IOException; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | @Order(1) | ||||||
|  | @Profile("filterExample") | ||||||
|  | public class EscapeHtmlFilter implements Filter { | ||||||
|  |     Logger logger = LoggerFactory.getLogger(EscapeHtmlFilter.class); | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) | ||||||
|  |             throws IOException, ServletException { | ||||||
|  |         logger.info("Modify the request"); | ||||||
|  | 
 | ||||||
|  |         filterChain.doFilter(new EscapeHtmlRequestWrapper((HttpServletRequest) servletRequest), servletResponse); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,19 @@ | |||||||
|  | package com.baeldung.modifyrequest.interceptor; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.modifyrequest.requestwrapper.EscapeHtmlRequestWrapper; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.web.servlet.HandlerInterceptor; | ||||||
|  | 
 | ||||||
|  | import javax.servlet.http.HttpServletRequest; | ||||||
|  | import javax.servlet.http.HttpServletResponse; | ||||||
|  | 
 | ||||||
|  | public class EscapeHtmlRequestInterceptor implements HandlerInterceptor { | ||||||
|  |     private static final Logger logger = LoggerFactory.getLogger(EscapeHtmlRequestInterceptor.class); | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | ||||||
|  |         EscapeHtmlRequestWrapper escapeHtmlRequestWrapper = new EscapeHtmlRequestWrapper(request); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,68 @@ | |||||||
|  | package com.baeldung.modifyrequest.requestwrapper; | ||||||
|  | 
 | ||||||
|  | import javax.servlet.ReadListener; | ||||||
|  | import javax.servlet.ServletInputStream; | ||||||
|  | import javax.servlet.http.HttpServletRequest; | ||||||
|  | import javax.servlet.http.HttpServletRequestWrapper; | ||||||
|  | import java.io.*; | ||||||
|  | 
 | ||||||
|  | public class EscapeHtmlRequestWrapper extends HttpServletRequestWrapper { | ||||||
|  |     private String body = null; | ||||||
|  |     public EscapeHtmlRequestWrapper(HttpServletRequest request) throws IOException { | ||||||
|  |         super(request); | ||||||
|  |         this.body = this.escapeHtml(request); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private String escapeHtml(HttpServletRequest request) throws IOException { | ||||||
|  |         StringBuilder stringBuilder = new StringBuilder(); | ||||||
|  |         BufferedReader bufferedReader = null; | ||||||
|  |         try (InputStream inputStream = request.getInputStream()) { | ||||||
|  |             bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); | ||||||
|  |             char[] charBuffer = new char[128]; | ||||||
|  |             int bytesRead = -1; | ||||||
|  |             while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { | ||||||
|  |                 stringBuilder.append(charBuffer, 0, bytesRead); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         String input = stringBuilder.toString(); | ||||||
|  |         // Escape HTML characters | ||||||
|  |         return input.replaceAll("&", "&") | ||||||
|  |                 .replaceAll("<", "<") | ||||||
|  |                 .replaceAll(">", ">") | ||||||
|  |                 //.replaceAll("\"", """) | ||||||
|  |                 .replaceAll("'", "'"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public ServletInputStream getInputStream() { | ||||||
|  |         final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); | ||||||
|  |         ServletInputStream servletInputStream = new ServletInputStream() { | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public int read() { | ||||||
|  |                 return byteArrayInputStream.read(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public boolean isFinished() { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public boolean isReady() { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void setReadListener(ReadListener listener) { | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |         return servletInputStream; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public BufferedReader getReader() throws IOException { | ||||||
|  |         return new BufferedReader(new InputStreamReader(this.getInputStream())); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | @startuml | ||||||
|  | 'https://plantuml.com/sequence-diagram | ||||||
|  | skinparam sequenceMessageAlign direction | ||||||
|  | skinparam handwritten true | ||||||
|  | skinparam sequence { | ||||||
|  | ParticipantBackgroundColor beige | ||||||
|  | ParticipantPadding 50 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | autonumber | ||||||
|  | 
 | ||||||
|  | Browser -[#63b175]> Filter: HTTP Request | ||||||
|  | activate Browser | ||||||
|  | activate Filter | ||||||
|  | Filter -[#63b175]> Filter: doFilter() | ||||||
|  | Filter -[#63b175]> DispatcherServlet: HTTP Request | ||||||
|  | activate DispatcherServlet | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | DispatcherServlet -[#63b175]> Controller: HTTP Request | ||||||
|  | activate Controller | ||||||
|  | Controller --[#63b175]> DispatcherServlet: HTTP Response | ||||||
|  | deactivate Controller | ||||||
|  | 
 | ||||||
|  | DispatcherServlet --[#63b175]> Filter: HTTP Response | ||||||
|  | deactivate DispatcherServlet | ||||||
|  | 
 | ||||||
|  | Filter --[#63b175]> Browser: HTTP Response | ||||||
|  | deactivate Filter | ||||||
|  | deactivate Browser | ||||||
|  | @enduml | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | @startuml | ||||||
|  | 'https://plantuml.com/sequence-diagram | ||||||
|  | skinparam sequenceMessageAlign direction | ||||||
|  | skinparam handwritten true | ||||||
|  | skinparam sequence { | ||||||
|  | ParticipantBackgroundColor beige | ||||||
|  | ParticipantPadding 50 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | autonumber | ||||||
|  | 
 | ||||||
|  | Browser -[#63b175]> Filter: Http Request | ||||||
|  | activate Browser | ||||||
|  | activate Filter | ||||||
|  | Filter -[#63b175]> DispatcherServlet: Http Request | ||||||
|  | activate DispatcherServlet | ||||||
|  | 
 | ||||||
|  | DispatcherServlet -[#63b175]> Interceptor: Http Request | ||||||
|  | activate Interceptor | ||||||
|  | Interceptor -[#63b175]> Interceptor: preHandle() | ||||||
|  | Interceptor -[#63b175]> Controller: Http Request | ||||||
|  | activate Controller | ||||||
|  | Controller --[#63b175]> Interceptor: Http Response | ||||||
|  | deactivate Controller | ||||||
|  | Interceptor --[#63b175]> DispatcherServlet: Http Response | ||||||
|  | deactivate Interceptor | ||||||
|  | DispatcherServlet --[#63b175]> Filter: Http Response | ||||||
|  | deactivate DispatcherServlet | ||||||
|  | 
 | ||||||
|  | Filter --[#63b175]> Browser: Http Response | ||||||
|  | deactivate Filter | ||||||
|  | deactivate Browser | ||||||
|  | @enduml | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | package com.baeldung.modifyrequest; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.modifyrequest.controller.UserController; | ||||||
|  | import com.fasterxml.jackson.databind.ObjectMapper; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.junit.jupiter.api.extension.ExtendWith; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.test.context.ActiveProfiles; | ||||||
|  | import org.springframework.test.context.junit.jupiter.SpringExtension; | ||||||
|  | import org.springframework.test.web.servlet.MockMvc; | ||||||
|  | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | ||||||
|  | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; | ||||||
|  | 
 | ||||||
|  | import java.net.URI; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | @ExtendWith(SpringExtension.class) | ||||||
|  | @AutoConfigureMockMvc | ||||||
|  | @WebMvcTest(UserController.class) | ||||||
|  | @ActiveProfiles("aspectExample") | ||||||
|  | public class EscapeHtmlAspectIntegrationTest { | ||||||
|  |     Logger logger = LoggerFactory.getLogger(EscapeHtmlAspectIntegrationTest.class); | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private MockMvc mockMvc; | ||||||
|  |     @Test | ||||||
|  |     void givenAspect_whenEscapeHtmlAspect_thenEscapeHtml() throws Exception { | ||||||
|  | 
 | ||||||
|  |         Map<String, String> requestBody = Map.of( | ||||||
|  |                 "name", "James Cameron", | ||||||
|  |                 "email", "<script>alert()</script>james@gmail.com" | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         Map<String, String> expectedResponseBody = Map.of( | ||||||
|  |                 "name", "James Cameron", | ||||||
|  |                 "email", "<script>alert()</script>james@gmail.com" | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         ObjectMapper objectMapper = new ObjectMapper(); | ||||||
|  | 
 | ||||||
|  |         mockMvc.perform(MockMvcRequestBuilders.post(URI.create("/save")) | ||||||
|  |           .contentType(MediaType.APPLICATION_JSON) | ||||||
|  |           .content(objectMapper.writeValueAsString(requestBody))) | ||||||
|  |           .andExpect(MockMvcResultMatchers.status().isCreated()) | ||||||
|  |           .andExpect(MockMvcResultMatchers.content().json(objectMapper.writeValueAsString(expectedResponseBody))); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | package com.baeldung.modifyrequest; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.modifyrequest.controller.UserController; | ||||||
|  | import com.fasterxml.jackson.databind.ObjectMapper; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.junit.jupiter.api.extension.ExtendWith; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.test.context.ActiveProfiles; | ||||||
|  | import org.springframework.test.context.junit.jupiter.SpringExtension; | ||||||
|  | import org.springframework.test.web.servlet.MockMvc; | ||||||
|  | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | ||||||
|  | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; | ||||||
|  | 
 | ||||||
|  | import java.net.URI; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | @ExtendWith(SpringExtension.class) | ||||||
|  | @AutoConfigureMockMvc | ||||||
|  | @WebMvcTest(UserController.class) | ||||||
|  | @ActiveProfiles("filterExample") | ||||||
|  | public class EscapeHtmlFilterIntegrationTest { | ||||||
|  |     Logger logger = LoggerFactory.getLogger(EscapeHtmlFilterIntegrationTest.class); | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private MockMvc mockMvc; | ||||||
|  |     @Test | ||||||
|  |     void givenFilter_whenEscapeHtmlFilter_thenEscapeHtml() throws Exception { | ||||||
|  |         Map<String, String> requestBody = Map.of( | ||||||
|  |                 "name", "James Cameron", | ||||||
|  |                 "email", "<script>alert()</script>james@gmail.com" | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         Map<String, String> expectedResponseBody = Map.of( | ||||||
|  |                 "name", "James Cameron", | ||||||
|  |                 "email", "<script>alert()</script>james@gmail.com" | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         ObjectMapper objectMapper = new ObjectMapper(); | ||||||
|  | 
 | ||||||
|  |         mockMvc.perform(MockMvcRequestBuilders.post(URI.create("/save")) | ||||||
|  |           .contentType(MediaType.APPLICATION_JSON) | ||||||
|  |           .content(objectMapper.writeValueAsString(requestBody))) | ||||||
|  |           .andExpect(MockMvcResultMatchers.status().isCreated()) | ||||||
|  |           .andExpect(MockMvcResultMatchers.content().json(objectMapper.writeValueAsString(expectedResponseBody))); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,46 @@ | |||||||
|  | package com.baeldung.modifyrequest; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.modifyrequest.controller.UserController; | ||||||
|  | import com.fasterxml.jackson.databind.ObjectMapper; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.junit.jupiter.api.extension.ExtendWith; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.test.context.ActiveProfiles; | ||||||
|  | import org.springframework.test.context.junit.jupiter.SpringExtension; | ||||||
|  | import org.springframework.test.web.servlet.MockMvc; | ||||||
|  | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; | ||||||
|  | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; | ||||||
|  | 
 | ||||||
|  | import java.net.URI; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ExtendWith(SpringExtension.class) | ||||||
|  | @AutoConfigureMockMvc | ||||||
|  | @WebMvcTest(UserController.class) | ||||||
|  | @ActiveProfiles("interceptorExample") | ||||||
|  | public class EscapeHtmlInterceptorIntegrationTest { | ||||||
|  |     Logger logger = LoggerFactory.getLogger(EscapeHtmlInterceptorIntegrationTest.class); | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private MockMvc mockMvc; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenInterceptor_whenEscapeHtmlInterceptor_thenEscapeHtml() throws Exception { | ||||||
|  |         Map<String, String> requestBody = Map.of( | ||||||
|  |                 "name", "James Cameron", | ||||||
|  |                 "email", "<script>alert()</script>james@gmail.com" | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         ObjectMapper objectMapper = new ObjectMapper(); | ||||||
|  |         mockMvc.perform(MockMvcRequestBuilders.post(URI.create("/save")) | ||||||
|  |           .contentType(MediaType.APPLICATION_JSON) | ||||||
|  |           .content(objectMapper.writeValueAsString(requestBody))) | ||||||
|  |           .andExpect(MockMvcResultMatchers.status().is4xxClientError()); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user