Mam aplikację Spring Boot, która używa Spring MVC w zwykły sposób, z kilkoma metodami, definicjami Freemarker i tym podobnymi. To wszystko jest powiązane z klasą WebMvcConfigurerAdapter
.Jak analizować adres URL i uruchamiać metodę ze "odbiciem" Spring MVC?
Chciałbym świadczyć usługę, w której użytkownik przesyła listę prawidłowych adresów URL, a aplikacja webowa wyszuka, który kontroler zostanie wywołany, przekaże parametry i zwróci łączny wynik dla każdego adresu URL - wszystko w jedna prośba.
W ten sposób użytkownik nie będzie musiał wykonywać setek połączeń HTTP, ale w razie potrzeby nadal będzie mógł wysyłać jednorazowe żądania. Idealnie byłoby po prostu wstrzyknąć automatycznie skonfigurowany komponent Spring bean, więc nie muszę powtarzać adresu URL, który został rozwiązany i przystosowany do obsługi Springa, a lista kontrolerów innych kontrolerów nigdy nie byłaby zsynchronizowana z prawdziwa lista kontrolerów.
Spodziewałem się napisać coś takiego (uproszczony do czynienia z jednym tylko URL, który jest bez sensu, ale łatwiejsze do zrozumienia):
@Autowired BeanThatSolvesAllMyProblems allMappings;
@PostMapping(path = "/encode", consumes = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String encode(@RequestBody String inputPath) {
if (allMappings.hasMappingForPath(inputPath)) {
return allMappings.getMapping(inputPath).execute();
} else {
return "URL didn't match, sorry";
}
}
Zamiast tego, miałem do zdefiniowania Wiosenne fasolę ja nie wiedzą, co robią i zostały powtarzając niektóre, co Wiosna ma zrobić dla mnie, który jestem zmartwiony nie zadziała dość samo jak to będzie, gdy użytkownik po prostu sprawiło, że nazywają się:
// these two are @Beans, with just their default constructor called.
@Autowired RequestMappingHandlerMapping handlers;
@Autowired RequestMappingHandlerAdapter adapter;
@PostMapping(path = "/encode", consumes = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String encode(@RequestBody String inputText) {
final HttpServletRequest mockRequest = new MockHttpServletRequest(null, inputText);
final StringBuilder result = new StringBuilder();
this.handlers.getHandlerMethods().forEach((requestMappingInfo, handlerMethod) -> {
if (requestMappingInfo.getPatternsCondition().getMatchingCondition(mockRequest) != null) {
try {
final MockHttpServletResponse mockResponse = new MockHttpServletResponse();
result.append("Result: ").append(adapter.handle(mockRequest, mockResponse, handlerMethod));
result.append(", ").append(mockResponse.getContentAsString());
result.append("\n");
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
});
return result.toString();
}
Myślałem, że robię całkiem dobrze idąc tą ścieżką, ale to nie działa z błędami Missing URI template variable
i nie tylko nie mam pojęcia, jak umieścić parametry żądania w (kolejna rzecz, którą Spring mogłaby poradzić sobie sama), ale nie jestem nawet pewien, czy to jest właściwym sposobem na zrobienie tego. Jak więc symulować żądanie Spring MVC "refleksyjnie", z samej aplikacji webowej?
Jakie są tutaj rzeczywiste korzyści? Zwykle klienci wysyłają dużo próśb i nie jest to problemem. Żądania muszą jeszcze zostać przesłane, a ich grupowanie w jakiś sposób nie zapewni znacznego przyspieszenia. – chrylis
Rzeczywistym przypadkiem użycia jest wyodrębnienie adresów URL z dokumentu i zwrócenie tego samego dokumentu z przetworzonymi wynikami, tak aby był dostępny w trybie offline (lub w przypadku awarii serwera). –
Następnie ponownie wywołaj połączenia. – chrylis