Я из Node-ExpressJS, так что я знаком с концепцией промежуточного программного обеспечения.Когда я изучал Spring, я узнал о компоненте под названием Filter
, который во многом отличается от промежуточного программного обеспечения в Express с некоторыми отличиями.
Поэтому я пытаюсь понять, как Filter
и FilterChain
на самом деле работает весной.
У меня есть следующий код:
Filter1.java
@Component
@Order(1)
public class Filter1 implements Filter {
.....
.....
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
LOGGER.info("############# Invoking Filter1 ############");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
LOGGER.info("************ Moving on to next Filter");
LOGGER.info("Adding new Attribute");
req.setAttribute("Custom_Attribute_1", "TEST***TEST***TEST");
chain.doFilter(request, response);
resp.addHeader("1st Header", "1ST"); // Custom header that never shows up
LOGGER.info("+++++++++ GOING BACK FROM Filter1 +++++++++");
}
}
Filter2.java
@Component
@Order(2)
public class Filter2 implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
LOGGER.info("############# Invoking Filter2 ####################");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
req.setAttribute("Filter2 Attribute", "2nd ORDER");
resp.addHeader("2nd Header", "2ND"); //Custom header that actually shows up
chain.doFilter(request, response);
LOGGER.info("+++++++++++ GOING BACK FROM Filter2 ++++++++++");
}
}
Controller.java
@RestController
public class Controller {
@GetMapping("/")
public ResponseEntity<Object> createResource(HttpServletRequest req) {
return new ResponseEntity<Object>("Resource Created",HttpStatus.OK);
}
}
Когда я отправляю запрос своему контроллеру с помощью Postman, я вижу только один из моих пользовательских заголовков в ответе, а именно 2nd Header
, но не вижу другой заголовок.
Заголовки ответа в Почтальоне
2nd Header → 2ND
Content-Type → text/plain;charset=UTF-8
Content-Length → 15
Date → Thu, 19 Sep 2019 20:16:25 GMT
Имеет ли какое-либо отношение к этому вызов chain.doFilter(request, response)
?Кажется, что не может быть никакой модификации объекта response
в классе Filter1
после вызова doFilter
из FilterChain
.
Что я пытаюсь понять здесь:
Если FilterChain.doFilter
- это то, что нужно вызвать для распространения объекта request
на следующие фильтры и, в конечном итоге, на контроллер, разве нельзя разрешить модификацию объекта response
послепозвонить на chain.doFilter
возврат?Как именно это работает внутри?Как вызов передает все вниз на контроллер, а затем возвращается к первому фильтру?
Кроме того, если Filter1 хотел увидеть телоответ после того, как он вернется из Filter2 и, возможно, изменить его, как бы он это сделал?