ControllerAdvice configuration not working - spring

I am having issues trying to get the controller advice working, Below is my code snippet. I have tired most of the answers on stackoverflow but havent had any success. I would appreciate if someone could guide me with this.
```
#ControllerAdvice
public class PollCoreExceptionHandler {
#ExceptionHandler(Exception.class)
public #ResponseBody ResponseException handleIllegalArgumentServiceException(
final Exception illegalArgumentServiceException) {
System.out.println("Error handling called ");
final ResponseException responseException = new ResponseException();
responseException.setErrorMessage("Error handler called " + illegalArgumentServiceException.getMessage());
return responseException;
}
}
```
My controller
```
#RequestMapping(value = "/login", method = RequestMethod.POST)
public UserDTO loginUser(#RequestBody final UserDTO userDto) throws Exception {
throw new Exception("error testing ");
}
```
Output
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 500 Server Error</title>
</head>
<body>
<h2>HTTP ERROR 500</h2>
<p>Problem accessing /ws/user/login. Reason:
<pre> Server Error</pre>
</p>
<h3>Caused by:</h3>
<pre>javax.servlet.ServletException: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.Exception: error testing
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:564)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:317)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128)
at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouK
</pre>
<h3>Caused by:</h3>
<pre>java.lang.Exception: error testing
at com.multi.enterprise.poll.core.controllers.UserController.loginUser(UserController.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet
I also see this when my app boots up.
2017-04-30 15:07:05,488 [main] INFO annotation.ExceptionHandlerExceptionResolver:273 () - Detected #ExceptionHandler methods in controllerAdvisor
2017-04-30 15:07:05,488 [main] INFO annotation.ExceptionHandlerExceptionResolver:273 () - Detected #ExceptionHandler methods in pollCoreExceptionHandler
2017-04-30 15:07:05,585 [main] INFO servlet.DispatcherServlet:508 () - FrameworkServlet 'dispatcher': initialization completed in 1213 ms

Related

Spring Thymeleafs Template Engine error during template parsing

I can see there are a few question already asked in there, but still I can't find any solution to fix my issue. I am using Spring boot Thymeleafs Template Engine to parse value attribute with Spring Context. Then, I can process PDF generated with flying-saucer-pdf.
I can say the problem is because String is passed to parameter and it is not referent to html file.
Error description:
2022-10-11T16:45:58.209+0700 ERROR [THYMELEAF][http-nio-8080-exec-2] Exception processing template "world-check-report": An error happened during template parsing (template: "applicationprocess/world-check-report.html")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "applicationprocess/world-check-report.html")
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:235) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:649) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) [thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1059) [thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1048) [thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at com.aeon.webadmin.controller.AssessmentController.getWorldCheckStatus(AssessmentController.java:820) [classes/:1.3.5]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_333]
Caused by: java.io.FileNotFoundException: ClassLoader resource "applicationprocess/world-check-report.html" could not be resolved
at org.thymeleaf.templateresource.ClassLoaderTemplateResource.reader(ClassLoaderTemplateResource.java:130) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
My Controller:
#PostMapping(value = "/world-check-info")
public ObjResponseEntity<AmlApplyLoan> getWorldCheckStatus(#RequestBody String aln_id) {
try {
HttpHeaders headers = new HttpHeaders();
AssessmentController assessmentController = new AssessmentController();
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("applicationprocess/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("XHTML");
templateResolver.setCharacterEncoding("UTF-8");
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
Context ctx = new Context();
ctx.setVariable("message", "TESTING");
//error here when parsing
String htmtContent = templateEngine.process("world-check-report", ctx);
return ObjResponseFactory.success();
} catch (Exception e) {
e.printStackTrace();
}
return ObjResponseFactory.fail();
Template File:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div class="content-wrapper" style="padding-left: 120px; font-family: sans-serif;">
<h2 class="page_title" th:text="${message}"></h2>
<h2>CASE REPORT</h2>
</div>
</body>
</html>

Spring Boot - Unit Test on Controller - 404 Answer

I am setting up the unit testing on my #RestController's, but It is not working correctly.
This is only a unit test to validate the answer from the method of the RestEndpoint, but It is not working, please help me because I tried a lot of configurations and read the documentation and nothing worked.
This is my endpoint:
#RestController
#RequestMapping("/clients")
public class ClientsEndpoint extends RestConfiguration {
#Autowired
private IClientService clientService;
#GetMapping(value = "/{id}")
private Object getById(#PathVariable(required = true) Long id) {
try {
Optional<Client> clientOptional = clientService.getById(id);
if (clientOptional.isPresent()) {
return clientOptional.get();
} else
return new GeneralResponse(ErrorsEnum.CLIENT_NOT_FOUND);
} catch (Exception e) {
log.log(Level.SEVERE, "Problemas al obtener datos del cliente con id: " + id, e);
return new GeneralResponse(ErrorsEnum.GENERAL_ERROR);
}
}
This is my Unit Test where I only added the mock of the endpoint and a simple call is done:
#RunWith(SpringRunner.class)
#WebMvcTest(ClientsEndpoint.class)
#ContextConfiguration(classes={ApplicationConfiguration.class})
public class QuarzoApiApplicationTests {
#Autowired
private MockMvc mockMvc;
#MockBean
private IClientService clientService;
#Test
public void getById() throws Exception {
Client client = new Client("Test", "Test", "Test", (byte) 1,
"Test", "Test", "Test", "Test", (byte) 1,
(byte) 1, (short)1, "Test" );
Optional<Client> clientOptional = Optional.of(client);
BDDMockito.given(clientService.getById(anyLong())).willReturn(clientOptional);
this.mockMvc.perform(get("/clients/1")
.header("Authorization","Bearer " + TestUtils.createToken("miltonc")))
.andExpect(status().isOk());
}
Results I am getting after running the unit test:
2019-08-27 10:01:18.505 INFO 23606 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#7da39774, org.springframework.security.web.context.SecurityContextPersistenceFilter#5b7c8930, org.springframework.security.web.header.HeaderWriterFilter#4277127c, org.springframework.web.filter.CorsFilter#441b8382, org.springframework.security.web.authentication.logout.LogoutFilter#1a6dc589, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#40e32762, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#6f231ced, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#1df1ced0, org.springframework.security.web.session.SessionManagementFilter#2c05ff9d, org.springframework.security.web.access.ExceptionTranslationFilter#2a8a4e0c, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#27755487]
2019-08-27 10:01:18.526 INFO 23606 --- [ main] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet ''
2019-08-27 10:01:18.527 INFO 23606 --- [ main] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2019-08-27 10:01:18.533 INFO 23606 --- [ main] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 6 ms
2019-08-27 10:01:18.555 INFO 23606 --- [ main] i.q.quarzoapi.QuarzoApiApplicationTests : Started QuarzoApiApplicationTests in 1.371 seconds (JVM running for 1.825)
MOCK org.springframework.test.web.servlet.MockMvc#770beef5
MockHttpServletRequest:
HTTP Method = GET
Request URI = /clients/1
Parameters = {}
Headers = [Authorization:"Bearer eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1NjY5MTQ0NzgsImlzcyI6IlFVQVJaTyIsInN1YiI6Im1pbHRvbmMiLCJleHAiOjE1NjY5NjQ4MDB9.hLu1Mcl_K-8smYnZnDu1ubkVTuNCkQnqhIQuypBsKBzQYxMlYlxqXhsYLCMB5iViCcDK33WXvO1Pjp15TR1ICg"]
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status
Expected :200
Actual :404
<Click to see difference>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:619)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:195)
at io.quarzo.quarzoapi.QuarzoApiApplicationTests.getById(QuarzoApiApplicationTests.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
2019-08-27 10:01:18.772 INFO 23606 --- [ Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
I finally solved this. I needed to include the #ComponentScan(basePackages = "io.quarzo.api.endpoints") to refer the endpoints I am trying to test.
My Test configuration:
#Configuration
#ComponentScan(basePackages = "io.quarzo.api.endpoints")
public class ApplicationConfiguration extends WebSecurityConfigurerAdapter {
After that, I had to Mock every bean I was using in the endpoints.
#MockBean(name = "clientRegistrationSingleton")
private Map<String, Client> clientsRegistering;
#MockBean
private IClientService clientService;
#MockBean
private IClientRepository clientRepository;
After that all was working ok, I can run the test and mock every Bean to test my #RestController's.

Spring-data-rest-webmvc: Why cannot the ObjectError be rendered directly when handling the exception - MethodArgumentNotValidException?

In light of the DefaultErrorAttributes, where ObjectError can be used to express the error details, I intended to utilize ObjectError to express the error details when handling the exception - MethodArgumentNotValidException` in the implementation of a REST API with pure Spring 5.
I handled MethodArgumentNotValidException by extends ResponseEntityExceptionHandler:
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.web.util.WebUtils;
#RestControllerAdvice
public class RestExceptionsHandler extends ResponseEntityExceptionHandler {
#Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { request.setAttribute(WebUtils.ERROR_STATUS_CODE_ATTRIBUTE, status.value(), RequestAttributes.SCOPE_REQUEST);
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, RequestAttributes.SCOPE_REQUEST);
BindingResult re = ((MethodArgumentNotValidException) ex).getBindingResult();
return new ResponseEntity<>(re.getAllErrors().get(0), headers, status);
}
}
In the code above, the BindingResult instance eventually called getAllErrors() to return a List of ObjectErrors. I just tried to get the first element from the List of ObjectErrors, and then presumably would render the ObjectError in JSON format for testing purpose. However, when running it with Jetty, even though the MethodArgumentNotValidException is handled in the mentioned exception handler - handleMethodArgumentNotValid (this is proved with debugger), the JSON for ObjectError could not be rendered in JSON format, instead the default html error page of the Jetty web container is displayed
The error html code generated from Jetty is the following:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 400 Bad Request</title>
</head>
<body>
<h2>HTTP ERROR 400</h2>
<p>Problem accessing /masterdata/cities. Reason:
<pre> Bad Request</pre>
</p>
<h3>Caused by:</h3>
<pre>org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.rx.entity.City com.rx.rest.controller.CityController.createCity(com.rx.entity.City): [Field error in object &apos;city&apos; on field &apos;city&apos;: rejected value [null]; codes [NotNull.city.city,NotNull.city,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [city.city,city]; arguments []; default message [city]]; default message [city cannot be empty]]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:138)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:166)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:859)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1623)
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:214)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:502)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.lang.Thread.run(Thread.java:748)
</pre>
<hr>
Powered by Jetty:// 9.4.14.v20181114
<hr/>
</body>
</html>
Quetion: Why cannot the ObjectError be rendered directly when handling the exception - MethodArgumentNotValidException?

Getting connection timed out error in microservice

I have built a microservice using Java 8 and SpringBoot 2. From this microservice, I'm trying to consume another REST API service. However, I'm getting the following error on Chrome. I have already disabled the windows firewall and McAfee antivirus firewall but still getting the same error. I can call the REST API directly using the Postman tool but not through my microservice.
Error:-
java.lang.IllegalStateException: The underlying HTTP client completed
without emitting a response.
2018-06-12 15:21:29.300 ERROR 17996 --- [ctor-http-nio-3]
.a.w.r.e.DefaultErrorWebExceptionHandler : Failed to handle request
[GET http://localhost:8080/category/search]
io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection
timed out: no further information: test.usdemo.xyz.com/92.54.41.24:443
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
~[na:1.8.0_171] at
sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
~[na:1.8.0_171] at
io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:325)
~[netty-transport-4.1.24.Final.jar:4.1.24.Final] at
io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:340)
~[netty-transport-4.1.24.Final.jar:4.1.24.Final] at
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:633)
~[netty-transport-4.1.24.Final.jar:4.1.24.Final] at
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
~[netty-transport-4.1.24.Final.jar:4.1.24.Final] at
io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
~[netty-transport-4.1.24.Final.jar:4.1.24.Final] at
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
~[netty-transport-4.1.24.Final.jar:4.1.24.Final] at
io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
~[netty-common-4.1.24.Final.jar:4.1.24.Final] at
java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_171] Caused by:
java.net.ConnectException: Connection timed out: no further
information ... 10 common frames omitted
Controller class:-
#RestController
public class CategorySearchController {
private final CategorySearchService categorySearchService;
#Autowired
public CategorySearchController(CategorySearchService categorySearchService) {
this.categorySearchService = categorySearchService;
}
#GetMapping(path = "/search-category")
public Mono<CategoryResponse> searchCategories(SearchRequest categorySearchRequest){
return categorySearchService
.searchCategories()
.switchIfEmpty(Mono.error(
new EntityNotFoundException("No category matching " + categorySearchRequest.getSearchTerm() + " was found")));
}
}
Service class:-
#Service
public class CategorySearchServiceImpl implements CategorySearchService {
private String baseUrl = "https://demo0954903.mockable.io";
#Override
public Mono<CategoryResponse> searchCategories() {
WebClient webClient = WebClient.create(baseUrl);
return webClient.
get()
.uri("/category-search")
.retrieve()
.bodyToMono(CategoryResponse.class);
}
}
I found the solution for this issue. I need to add the proxy in the webclient as follows:-
private final WebClient webClient;
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(
options -> options.httpProxy(addressSpec -> {
return addressSpec.host(PROXY_HOST).port(PROXY_PORT);
}));
this.webClient = webClientBuilder.baseUrl(BASE_URL).clientConnector(connector).build();

IntegrationFlow Exception Handling

I am trying to create a Flow for message as follow:
TCPinboundAdapter ----> Message Brocker(ActiveMQ)
Flow:
This flow is created in the following way
The message is received via TCP connection to TCP Adapter which may be client or server.
The message received to TCP adapter is send to JMS Adapter(ActiveMQ Broker).
The code is as follow:
#EventListener
public void handleTcpConnectionClientEvent(TcpConnectionFailedEvent event){
TcpNioClientConnectionFactory tcp = (TcpNioClientConnectionFactory)event.getSource();
System.out.println(tcp);
System.out.println("connection exception client :::"+event.getSource());
this.status = event.toString();
}
#EventListener
public void handleTcpConnectionServerExceptionEvent(TcpConnectionServerExceptionEvent event){
System.out.println("connection exception server :::");
this.status = event.toString();
}
// this method is invoked when the connection with the sever got disconnected
#EventListener
public void handleTcpConnectionServerEvent(TcpConnectionExceptionEvent event){
System.out.println("connection exception serversssss :::"+event.getConnectionFactoryName());
this.status = event.toString();
}
//when the connection got established (not for first time)
#EventListener
public void handleTcpConnectionCloseEvent(TcpConnectionOpenEvent event){
System.out.println("connection opened :::"+event.getConnectionFactoryName());
// status = event.toString();
}
// create a server connection and flow to JMS
private void createServerConnection(HostConnection hostConnection) throws Throwable{
this.status = "success";
// IntegrationFlow flow;
IntegrationFlowRegistration theFlow;
IntegrationFlow flow =
IntegrationFlows.from(Tcp.inboundAdapter(Tcp.netServer(1234)
.serializer(customSerializer)
.deserializer(customSerializer)
.id(hostConnection.getConnectionNumber()).soTimeout(10000)))
.enrichHeaders(f->f.header("abc","abc")))
.channel(directChannel())
.handle(Jms.outboundAdapter(ConnectionFactory())
.destination("jmsInbound"))
.get();
theFlow = this.flowContext.registration(flow).id("test.flow").register();
if(this.status.equals("success"))
createInboundFlow(hostConnection);
// startConnection(hostConnection.getConnectionNumber());
}
Issue:
This flow is created successfully and get registered to Application Context when there is no Exception.
But in case When there is an exception i.e (BindException)
When creating server to a particular port and the Port is already used
then it raise BindException then also the flow got registered
So, we want that the flow should not be registered when there is exception in any of the flow component below.
IntegrationFlowRegistration theFlow;
IntegrationFlow flow =
IntegrationFlows.from(Tcp.inboundAdapter(Tcp.netServer(1234)
.serializer(customSerializer)
.deserializer(customSerializer)
.id("server").soTimeout(10000)))
.enrichHeaders(f->f.header("abc","abc")))
.channel(directChannel())
.handle(Jms.outboundAdapter(ConnectionFactory())
.destination("jmsInbound"))
.get();
theFlow =this.flowContext.registration(flow).id("test.flow").register();
There are various Listener implemented to check exception in TCP connection try{}catch() block don't raise any exception.
Please provide a suitable approach to handle Exceptions for adapters currently I am using Listeners for various event to know there is something wrong with the tcp adapters.
After applying this approach provided by Mr. Artem Bilan
#EventListener
public void handleTcpConnectionServerExceptionEvent(TcpConnectionServerExceptionEvent event){
System.out.println("connection exception server :::"+event);
this.status = event.getCause().getMessage();
AbstractConnectionFactory server = (AbstractConnectionFactory)event.getSource();
System.out.println(server.getComponentName());
this.flowContext.remove(server.getComponentName()+"out.flow");
}
I am able to remove the flow using FlowId but I am not able to catch the Exception
The Exception below is printing on the console and can't be handled Even I have changed method to
private void createServerConnection(HostConnection hostConnection) throws Throwable{}
and handled these Exception with try{}catch(Throwable t){} in calling function
Exception in thread "pool-4-thread-1" java.lang.NullPointerException
Exception is described in more elaborated form in the logs provided below:
2018-05-17 21:01:40.850 INFO 18332 --- [nio-8080-exec-4]
.s.i.i.t.c.TcpNetServerConnectionFactory : started Co123, port=1234
2018-05-17 21:01:40.850 INFO 18332 --- [nio-8080-exec-4] o.s.i.ip.tcp.TcpReceivingChannelAdapter : started org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter#3
2018-05-17 21:01:40.851 ERROR 18332 --- [pool-5-thread-1] .s.i.i.t.c.TcpNetServerConnectionFactory : Error on ServerSocket; port = 1234
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method) ~[na:1.8.0_111]
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source) ~[na:1.8.0_111]
at java.net.AbstractPlainSocketImpl.bind(Unknown Source) ~[na:1.8.0_111]
at java.net.PlainSocketImpl.bind(Unknown Source) ~[na:1.8.0_111]
at java.net.ServerSocket.bind(Unknown Source) ~[na:1.8.0_111]
at java.net.ServerSocket.<init>(Unknown Source) ~[na:1.8.0_111]
at java.net.ServerSocket.<init>(Unknown Source) ~[na:1.8.0_111]
at javax.net.DefaultServerSocketFactory.createServerSocket(Unknown Source) ~[na:1.8.0_111]
at org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory.createServerSocket(TcpNetServerConnectionFactory.java:211) ~[spring-integration-ip-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory.run(TcpNetServerConnectionFactory.java:106) ~[spring-integration-ip-5.0.3.RELEASE.jar:5.0.3.RELEASE]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_111]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_111]
connection exception server :::TcpConnectionServerExceptionEvent [source=Co123, port=1234, cause=java.net.BindException: Address already in use: JVM_Bind]
Co123
2018-05-17 21:01:40.851 INFO 18332 --- [pool-5-thread-1] o.s.i.ip.tcp.TcpReceivingChannelAdapter : stopped org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter#3
2018-05-17 21:01:40.851 INFO 18332 --- [pool-5-thread-1] o.s.i.endpoint.EventDrivenConsumer : Removing {transformer} as a subscriber to the 'Co123out.flow.channel#0' channel
2018-05-17 21:01:40.852 INFO 18332 --- [pool-5-thread-1] o.s.integration.channel.DirectChannel : Channel 'application.Co123out.flow.channel#0' has 0 subscriber(s).
2018-05-17 21:01:40.852 INFO 18332 --- [pool-5-thread-1] o.s.i.endpoint.EventDrivenConsumer : stopped org.springframework.integration.config.ConsumerEndpointFactoryBean#11
2018-05-17 21:01:40.852 INFO 18332 --- [pool-5-thread-1] o.s.i.endpoint.EventDrivenConsumer : Removing {jms:outbound-channel-adapter} as a subscriber to the 'Co123out.flow.channel#1' channel
2018-05-17 21:01:40.852 INFO 18332 --- [pool-5-thread-1] o.s.integration.channel.DirectChannel : Channel 'application.Co123out.flow.channel#1' has 0 subscriber(s).
2018-05-17 21:01:40.852 INFO 18332 --- [pool-5-thread-1] o.s.i.endpoint.EventDrivenConsumer : stopped org.springframework.integration.config.ConsumerEndpointFactoryBean#12
Exception in thread "pool-4-thread-1" java.lang.NullPointerException
at org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory.run(TcpNetServerConnectionFactory.java:185)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception in thread "pool-5-thread-1" java.lang.NullPointerException
at org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory.run(TcpNetServerConnectionFactory.java:185)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)`
You register an IntegrationFlow via:
this.flowContext.registration(flow).id("test.flow").register();
The same his.flowContext bean and that id for the flow can be used to destroy the flow from any other place, e.g. an event listener, when you catch the mentioned BindException:
/**
* Destroy an {#link IntegrationFlow} bean (as well as all its dependant beans)
* for provided {#code flowId} and clean up all the local cache for it.
* #param flowId the bean name to destroy from
*/
void remove(String flowId);

Resources