SpringBoot cannot find handler method - spring-boot

I have a basic SpringBoot app. using Spring Initializer, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file.
this is the main class
#SpringBootApplication
public class TdkApplication {
public static void main(String[] args) {
SpringApplication.run(TdkApplication.class, args);
}
}
This is a controller
#Controller
public class MockupIndexController {
#RequestMapping("/mockup/index")
public String welcome(Map<String, Object> model) {
return "mockups/index";
}
}
This my pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.tdk.iot.core</groupId>
<artifactId>tdk-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
But when I put this in the URL:
http://localhost:8080/mockup/index
I got the following log in the console
o.s.web.servlet.DispatcherServlet : Servlet 'dispatcherServlet' configured successfully
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/mockup/index]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /mockup/index
s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/mockup/index]
o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/mockup/index] are [/**]
o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/mockup/index] are {}
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/mockup/index] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#8b91134]]] and 1 interceptor
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/mockup/index] is: -1
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error

I assume your controller class is not found during scanning cause it is in a package that will not be scanned by default. I guess your application is in something like com.tdk.app and your controller in com.tdk.controller, right? If yes just move the app one level up to com.tdk and your issue should go away.

The controller package should be the one level bottom package of "TdkApplication" if your "TdkApplication" is in com.test package, Then your controller should be under com.test.controller package. Means one level down package when we comparing with application package

following will work
App package should be like com.app
then controller would be com.app.controller.
if you use it like below then spring would be unable to scan the controller
App package: com.app.main
controller:com.app.controller

Related

Spring boot returns an empty list [duplicate]

I am trying to adapt the REST Controller example on the Spring Boot website.
Unfortunately I've got the following error when I am trying to access the localhost:8080/item URL.
{
"timestamp": 1436442596410,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/item"
}
POM:
<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>
<groupId>SpringBootTest</groupId>
<artifactId>SpringBootTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<javaVersion>1.8</javaVersion>
<mainClassPackage>com.nice.application</mainClassPackage>
<mainClass>${mainClassPackage}.InventoryApp</mainClass>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${javaVersion}</source>
<target>${javaVersion}</target>
</configuration>
</plugin>
<!-- Makes the Spring Boot app executable for a jar file. The additional configuration is needed for the cmd: mvn spring-boot:repackage
OR mvn spring-boot:run -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${mainClass}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Create a jar with a manifest -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot. This replaces the usage of the Spring Boot parent POM file. -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- more comfortable usage of several features when developing in an IDE. Developer tools are automatically disabled when
running a fully packaged application. If your application is launched using java -jar or if it’s started using a special classloader,
then it is considered a 'production application'. Applications that use spring-boot-devtools will automatically restart whenever files
on the classpath change. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
</dependency>
</dependencies>
</project>
Starter-Application:
package com.nice.application;
#SpringBootApplication // same as #Configuration #EnableAutoConfiguration #ComponentScan
public class InventoryApp {
public static void main( String[] args ) {
SpringApplication.run( InventoryApp.class, args );
}
}
REST-Controller:
package com.nice.controller;
#RestController // shorthand for #Controller and #ResponseBody rolled together
public class ItemInventoryController {
public ItemInventoryController() {
}
#RequestMapping( "/item" )
public String getStockItem() {
return "It's working...!";
}
}
I am building this project with Maven.
Started it as jar (spring-boot:run) and as well inside the IDE (Eclipse).
Console Log:
2015-07-09 14:21:52.132 INFO 1204 --- [ main] c.b.i.p.s.e.i.a.InventoryApp : Starting InventoryApp on 101010002016M with PID 1204 (C:\eclipse_workspace\SpringBootTest\target\classes started by MFE in C:\eclipse_workspace\SpringBootTest)
2015-07-09 14:21:52.165 INFO 1204 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#7a3d45bd: startup date [Thu Jul 09 14:21:52 CEST 2015]; root of context hierarchy
2015-07-09 14:21:52.661 INFO 1204 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2015-07-09 14:21:53.430 INFO 1204 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2015-07-09 14:21:53.624 INFO 1204 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2015-07-09 14:21:53.625 INFO 1204 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.23
2015-07-09 14:21:53.731 INFO 1204 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2015-07-09 14:21:53.731 INFO 1204 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1569 ms
2015-07-09 14:21:54.281 INFO 1204 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2015-07-09 14:21:54.285 INFO 1204 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2015-07-09 14:21:54.285 INFO 1204 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2015-07-09 14:21:54.508 INFO 1204 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for #ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#7a3d45bd: startup date [Thu Jul 09 14:21:52 CEST 2015]; root of context hierarchy
2015-07-09 14:21:54.573 INFO 1204 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2015-07-09 14:21:54.573 INFO 1204 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2015-07-09 14:21:54.594 INFO 1204 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-07-09 14:21:54.594 INFO 1204 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-07-09 14:21:54.633 INFO 1204 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2015-07-09 14:21:54.710 INFO 1204 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2015-07-09 14:21:54.793 INFO 1204 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2015-07-09 14:21:54.795 INFO 1204 --- [ main] c.b.i.p.s.e.i.a.InventoryApp : Started InventoryApp in 2.885 seconds (JVM running for 3.227)
2015-07-09 14:22:10.911 INFO 1204 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2015-07-09 14:22:10.911 INFO 1204 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2015-07-09 14:22:10.926 INFO 1204 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 15 ms
What I've tried so far:
Accessing the URL with the application name (InventoryApp)
Put another #RequestMapping("/") at class level of the ItemInventoryController
As far as I understood, I won't need an application-context when using Spring Boot. Am I right?
What else can I do to access the method via URL?
Try adding the following to your InventoryApp class
#SpringBootApplication
#ComponentScan(basePackageClasses = ItemInventoryController.class)
public class InventoryApp {
...
spring-boot will scan for components in packages below com.nice.application, so if your controller is in com.nice.controller you need to scan for it explicitly.
Adding to MattR's answer:
As stated in here, #SpringBootApplication automatically inserts the needed annotations: #Configuration, #EnableAutoConfiguration, and also #ComponentScan; however, the #ComponentScan will only look for the components in the same package as the App, in this case your com.nice.application, whereas your controller resides in com.nice.controller. That's why you get 404 because the App didn't find the controller in the application package.
Same 404 response I got after service executed with the below code
#Controller
#RequestMapping("/duecreate/v1.0")
public class DueCreateController {
}
Response:
{
"timestamp": 1529692263422,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/duecreate/v1.0/status"
}
after changing it to below code I received proper response
#RestController
#RequestMapping("/duecreate/v1.0")
public class DueCreateController {
}
Response:
{
"batchId": "DUE1529673844630",
"batchType": null,
"executionDate": null,
"status": "OPEN"
}
SpringBoot developers recommend to locate your main application class in a root package above other classes. Using a root package also allows the #ComponentScan annotation to be used without needing to specify a basePackage attribute. Detailed info
But be sure that the custom root package exists.
There are 2 method to overcome this
Place the bootup application at start of the package structure and rest all controller inside it.
Example :
package com.spring.boot.app; - You bootup application(i.e. Main Method -SpringApplication.run(App.class, args);)
You Rest Controller in with the same package structure
Example :
package com.spring.boot.app.rest;
Explicitly define the Controller in the Bootup package.
Method 1 is more cleaner.
I had this issue and what you need to do is fix your packages. If you downloaded this project from http://start.spring.io/ then you have your main class in some package. For example if the package for the main class is: "com.example" then and your controller must be in package: "com.example.controller". Hope this helps.
The controller should be accessible in the same namespace
This is what you have
This is how it should be, see the hierarchy of the namespace
You need to modify the Starter-Application class as shown below.
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan(basePackages="com.nice.application")
#EnableJpaRepositories("com.spring.app.repository")
public class InventoryApp extends SpringBootServletInitializer {..........
And update the Controller, Service and Repository packages structure as I mentioned below.
Example:
REST-Controller
package com.nice.controller; --> It has to be modified as
package com.nice.application.controller;
You need to follow proper package structure for all packages which are in Spring Boot MVC flow.
So, If you modify your project bundle package structures correctly then your spring boot app will work correctly.
Replace #RequestMapping( "/item" ) with #GetMapping(value="/item", produces=MediaType.APPLICATION_JSON_VALUE).
Maybe it will help somebody.
for me, I was adding spring-web instead of the spring-boot-starter-web into my pom.xml
when i replace it from spring-web to spring-boot-starter-web, all maping is shown in the console log.
I had exact same error, I was not giving base package. Giving correct base package,ressolved it.
package com.ymc.backend.ymcbe;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages="com.ymc.backend")
public class YmcbeApplication {
public static void main(String[] args) {
SpringApplication.run(YmcbeApplication.class, args);
}
}
Note: not including .controller
#ComponentScan(basePackages="com.ymc.backend.controller") because i
have many other component classes which my project does not scan if i
just give .controller
Here is my controller sample:
package com.ymc.backend.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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
#CrossOrigin
#RequestMapping(value = "/user")
public class UserController {
#PostMapping("/sendOTP")
public String sendOTP() {
return "OTP sent";
};
}
I found a really great thread for this issue.
https://coderanch.com/t/735307/frameworks/Spring-boot-Rest-api
The controller api should be in the sub directory structure to automatically detect the controllers. Otherwise annotation argument can be used.
#SpringBootApplication(scanBasePackages = {"com.example.demo", "com.example.Controller"})
Sometimes spring boot behaves weird. I specified below in application class and it works:
#ComponentScan("com.seic.deliveryautomation.controller")
I got the 404 problem, because of Url Case Sensitivity.
For example
#RequestMapping(value = "/api/getEmployeeData",method = RequestMethod.GET) should be accessed using http://www.example.com/api/getEmployeeData. If we are using http://www.example.com/api/getemployeedata, we'll get the 404 error.
Note:
http://www.example.com is just for reference which i mentioned above. It should be your domain name where you hosted your application.
After a lot of struggle and apply all the other answers in this post, I got that the problem is with that url only. It might be silly problem. But it cost my 2 hours. So I hope it will help someone.
It also works if we use as follows:
#SpringBootApplication(scanBasePackages = { "<class ItemInventoryController package >.*" })
It could be that something else is running on port 8080, and you're actually connecting to it by mistake.
Definitely check that out, especially if you have dockers that are bringing up other services you don't control, and are port forwarding those services.
The problem is with your package structure. Spring Boot Application has a specific package structure to allow spring context to scan and load various beans in its context.
In com.nice.application is where your Main Class is and in com.nice.controller, you have your controller classes.
Move your com.nice.controller package into com.nice.application so that Spring can access your beans.
Another solution in case it helps: in my case, the problem was that I had a #RequestMapping("/xxx") at class level (in my controller), and in the exposed services I had #PostMapping (value = "/yyyy") and #GetMapping (value = "/zzz"); once I commented the #RequestMapping("/xxx") and managed all at method level, worked like a charm.
For me, the problem was that I had set up the Application in a way that it always immediately shut down after starting. So by the time I tried out if I could access the controller, the Application wasn't running anymore.
The problem with immediately shutting down is adressed in this thread.
#SpringBootApplication
#ComponentScan(basePackages = {"com.rest"}) // basePackageClasses = HelloController.class)
// use above componnent scan to add packages
public class RestfulWebServicesApplication {
public static void main(String[] args) {
SpringApplication.run(RestfulWebServicesApplication.class, args);
}
}
There may 3 reasons causing for this error:
1>
check your URL you are requesting is correct
2> check if your
using MVC then use #Controller else use #RestController
3> check
whether you have placed Controller package(or Class) outside the root
package example: com.example.demo -> is your main
package
place controller package inside com.example.demo.controller
I had the same issue, because I created an inner class annotated with #Configuration and it prohibited somehow the component scan.
I had the same problem, and while the above solution are correct in their own right, they did not work for me, and I found another possible reason that solved it - you have to shut down the application from the port, and restart your application, if doing a Maven Update or a project clean fail to solve it.
Briefly, open a command prompt, and run the following two commands:
netstat -ano | findstr :8080
This command will locate the Process ID that is attached at the port that your app is running on - please make sure to specify the port, if you have it anywhere other than the default.
You will get the following output:
What you care about is the number in the last column, which is the process ID associated with the port, on which the instance of the app is running.
If you are using STS4 for your development purposes, you can also see the PID on the top margin of the console, but you do have to squint for it:
At this point, run the next command to kill the process:
taskkill /pid 22552 /f
And it results in this:
Do remember that there will be a different PID for every time you run the application.
And finally, you can run it again, and that should do it.
More relevant materials:
Closing network connections
Programmatically shutting down SpringBoot app
New to Springboot, tried everything above, but ended up being as simple as I had a / at the end of the URL on my browser while my only Get() method was blank, just returning a string.
Hope this'll help someone someday.
Change the Return type from String to ResponseEntity
Like :
#RequestMapping( "/item" )
public ResponseEntity<String> getStockItem() {
return new ResponseEntity<String>("It's working...!", HttpStatus.OK);
}
Place your springbootapplication class in root package for example if your service,controller is in springBoot.xyz package then your main class should be in springBoot package otherwise it will not scan below packages
You can add inside the POM.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>XXXXXXXXX</version>
</dependency>

Error while configuring View Resolver for mustache template engine

I have the following configuration file in spring-boot project :
#Configuration
public class AppConfig {
#Bean
public ViewResolver mustacheViewResolver() {
MustacheViewResolver viewResolver = new MustacheViewResolver();
viewResolver.setPrefix("/templates/");
viewResolver.setSuffix(".mustache");
viewResolver.setOrder(1);
return viewResolver;
}
}
When I run my application, I am getting the following error:
Description:
The bean 'mustacheViewResolver', defined in class path resource [org/springframework/boot/autoconfigure/mustache/MustacheServletWebConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/example/demo/AppConfig.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
I am not sure if I am configuring the view Resolver properly
Error after removing the configuration class:
o.s.w.s.v.ContentNegotiatingViewResolver : Selected '*/*' given [*/*]
o.s.w.servlet.view.InternalResourceView : View name 'tweets.mustache', model {tweets=null}
o.s.w.servlet.view.InternalResourceView : Forwarding to [tweets.mustache]
o.s.web.servlet.DispatcherServlet : "FORWARD" dispatch for GET "/tweets.mustache?email=tim#gmail.com", parameters={masked}
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
o.s.web.servlet.DispatcherServlet : Exiting from "FORWARD" dispatch, status 404
o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error?email=tim#gmail.com", parameters={masked}
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=, status=404, error=Not Found, path=/tweet2}]
o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
#GetMapping("/tweet2")
public ModelAndView getTweetsByEmail(#RequestParam String email) {
HQLExample.insertRecords();
ModelAndView modelAndView = new ModelAndView("tweets.mustache");
List<Tweet> tweets = tweetMap.get(email);
modelAndView.getModel().put("tweets",tweets);
return modelAndView;
}
Assuming you have added spring-boot-starter-mustache as a dependency (to easily include all needed dependencies). When Spring Boot detects Mustache on the classpath it will automatically configure the MustacheViewResolver which will load Mustache templates from /templates on the classpath. The files should end with .mustache.
With this in mind, just remove your AppConfig class as it interferes with the auto configuration.
In your controller the name of the view is the name you have but without the .mustache that will be added by the ViewResolver.
So in short you should remove things and it will work. Do more with less in this case.

Use thymeleaf template of another project

There seems to be problem if using thymeleaf for multiple projects.
Let's say I have a spring application in project 2 & the controller in project 1. With proper #ComponentScan defined, the application able to display the view/html in my template folder. But once I added the thymeleaf-layout-dialect maven dependency, it failed with "There was an unexpected error (type=Not Found, status=404)." error.
My projects:
The prj1 pom.xml:
<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>
<groupId>macrohard.org</groupId>
<artifactId>prj1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
</dependencies>
</project>
The prj2 pom.xml:
<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>
<groupId>macrohard.org</groupId>
<artifactId>prj2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>macrohard.org</groupId>
<artifactId>prj1</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
The hello-world.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>HW</title>
</head>
<body>
Hello World!!
</body>
</html>
The App2 in prj2:
package prj2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages = { "prj1"} )
public class App2 {
public static void main(String[] args) {
SpringApplication.run(App2.class, args);
}
}
The Controller1 in prj1
package prj1.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
#RestController
#RequestMapping(value="/api")
public class Controller1 {
// this can be run by App2 & App1
#GetMapping(value="/hello")
public String hello() {
return "hello world";
}
// this can be run by App1 only
#GetMapping(value="/hello2")
public ModelAndView hello2() {
ModelAndView mav = new ModelAndView();
mav.setViewName("hello-world");
return mav;
}
}
As in Controller1, The "api/hello" can be requested successfully because it doesn't involve the template. But for the "api/hello2" request, it unable to render the hello-world.html. Here are the error stacks:
2019-07-02 22:21:28.758 INFO 19680 --- [ main] prj2.App2 : Started App2 in 1.89 seconds (JVM running for 2.454)
2019-07-02 22:21:51.807 INFO 19680 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-07-02 22:21:51.807 INFO 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-07-02 22:21:51.807 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.multipart.support.StandardServletMultipartResolver#2ded92
2019-07-02 22:21:51.810 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No LocaleResolver 'localeResolver': using default [AcceptHeaderLocaleResolver]
2019-07-02 22:21:51.811 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No ThemeResolver 'themeResolver': using default [FixedThemeResolver]
2019-07-02 22:21:51.814 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No RequestToViewNameTranslator 'viewNameTranslator': using default [DefaultRequestToViewNameTranslator]
2019-07-02 22:21:51.817 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No FlashMapManager 'flashMapManager': using default [SessionFlashMapManager]
2019-07-02 22:21:51.817 DEBUG 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2019-07-02 22:21:51.817 INFO 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 10 ms
2019-07-02 22:21:51.829 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/api/hello2", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2019-07-02 22:21:51.834 TRACE 19680 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.web.servlet.ModelAndView prj1.web.Controller1.hello2()
2019-07-02 22:21:51.843 TRACE 19680 --- [nio-8080-exec-1] .w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: []
2019-07-02 22:21:51.851 DEBUG 19680 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9, */*;q=0.8]
2019-07-02 22:21:51.851 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'hello-world'; URL [hello-world]]
2019-07-02 22:21:51.851 DEBUG 19680 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView : View name 'hello-world', model {}
2019-07-02 22:21:51.853 DEBUG 19680 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView : Forwarding to [hello-world]
2019-07-02 22:21:51.857 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : "FORWARD" dispatch for GET "/api/hello-world", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2019-07-02 22:21:51.860 TRACE 19680 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to HandlerExecutionChain with [ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]] and 3 interceptors
2019-07-02 22:21:51.862 DEBUG 19680 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-07-02 22:21:51.862 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : No view rendering, null ModelAndView returned.
2019-07-02 22:21:51.862 DEBUG 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "FORWARD" dispatch, status 404, headers={}
2019-07-02 22:21:51.864 DEBUG 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND, headers={}
2019-07-02 22:21:51.865 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2019-07-02 22:21:51.865 TRACE 19680 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : 2 matching mappings: [{ /error, produces [text/html]}, { /error}]
2019-07-02 22:21:51.866 TRACE 19680 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2019-07-02 22:21:51.875 TRACE 19680 --- [nio-8080-exec-1] .w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: [org.apache.catalina.core.ApplicationHttpRequest#6fdc83, org.apache.catalina.connector.ResponseFacade#119a78b]
2019-07-02 22:21:51.885 DEBUG 19680 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2019-07-02 22:21:51.886 TRACE 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$StaticView#216e30]
2019-07-02 22:21:51.908 DEBUG 19680 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404, headers={}
I am certain that it is due to thymeleaf-layout-dialect, because if I remove it from pom.xml everything work fine.
The problem is I need it to layout thymeleaf page. How to display the template in another different project from spring application?
As you have published an example project, I can't follow the issue :/
Are you sure you did not just confuse the "hello world" messages from the controller with the message from the template?
When I modify: \prj1\src\main\resources\templates\hello-world.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>HW</title>
</head>
<body>
Hello World!! (from Template in prj1)!
</body>
</html>
I had to add this into pom.xml of prj1 because of some weird classpath issue:
(the thymeleaf-layout-dialect lib you use seems to bring in an additional thymeleaf jar - did not investigate that)
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
When I run prj2 app and call: http://localhost:8080/api/hello3 or http://localhost:8080/api/hello2
I get:
Hello World!! (from Template in prj1)!
Which is what we want?
When I call: http://localhost:8080/api/hello
I get an error because of some not found template ("hello world" is of course not a template file).
So I'm not sure why it does not work for you :/
I'm not sure how this works without that dependency. The controllers that work with templates can return the template name directly. And you are implementing rest controllers which suggest different defaults than required for working with templates (like the content types).
So a controller that would invoke a template looks like (this is my way of doing it, can't claim I know its the only one):
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
#Controller
public class MyController {
#Autowired
public MyController() {
}
#RequestMapping("/hello-world")
public String hello(Model model) {
model.addAttribute("someKey", "someValue");
return "hello-world"; // this is the template name in src/main/resources
}
}
And this way it is also possible to have controllers / templates bundled in one jar and use them in a different spring boot application as dependencies. Since it is all classpath based (there is a property to configure this: spring.thymeleaf.prefix) this just worked for me.
I think the reason really is your rest controller - which might confuse things a bit.

spring boot 1.4 jsp page not evaluated Forward InternalViewResolver

After 2 days of investigation, and looking a lot of answers about my issue, I cannot solve it.
I am not expert of spring framework.
Entry point :
I have generate a jhipster project a year ago. I want to embed jsp pages in my project.
I'm using spring boot 1.4 in a maven project
I have include dependency following :
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
I have created a new servlet in WebConfigurer class which implements ServletContextInitializer.onStartup and created a file named servletJsp-servlet.xml in a WEB-INF resources folder.
The xml instanciate InternalViewResolver with prefix /mesPages/ and suffix=.jsp
I created also a controller :
#Controller
public class TestJspController {
#RequestMapping(value = "/jsp/bbb")
public ModelAndView serveLog4jAdmin() {
return new ModelAndView("log4jAdmin");
}
}
I stick here : (see log below)
The logs say that :
Controller is well called
It returns well the ModelAndView
Launch Forward to resource [/mesPagesJsps/log4jAdmin.jsp] from InternalResourceView 'log4jAdmin'
But after that, instead of getting it and rendering it, no stacktrace and try to resolve jsp page with another servlet : dispatcherServlet (I believe this is the defaut spring autoconfigured and created) spring servlet.
The dispatcherServlet is successfull in getting it because I have put my folder mesPages (which contains my jsps) every where in the project (META-INF, WEB-INF, root folders) of resources and webapp
Finally, the jsp page is not evaluated, and broswer give me to download it as "application/octet-stream".
Previously before putting jsp on all these folders, I uses to have the same controller behaviour but ending with 404 error (blank page).
I really don't understand why app behave like this.
I have another spring (not boot) webapp which works well.
I tried to debug, but to complex for me ... When debugging I was just detect that the requestDispatcher cannot dispatch Forward because there is no Handler with type FORWARD in some 'next' variables.
I think this is the cause ...
If someone has some anwser, I would be very happy
I can give any other information that is required.
The concerned part of log :
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'servletJSP' processing GET request for [/jsps/jsp/bbb]
[ XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /jsp/bbb
[ XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView fr.softeam.testify.web.rest.jsp.TestJspController.serveLog4jAdmin()]
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/jsps/jsp/bbb] is: -1
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.JstlView: name 'log4jAdmin'; URL [/mesPagesJsps/log4jAdmin.jsp]] in DispatcherServlet with name 'servletJSP'
[ XNIO-3 task-2] o.s.web.servlet.view.JstlView : Forwarding to resource [/mesPagesJsps/log4jAdmin.jsp] in InternalResourceView 'log4jAdmin'
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/mesPagesJsps/log4jAdmin.jsp]
[ XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /mesPagesJsps/log4jAdmin.jsp
[ XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/mesPagesJsps/log4jAdmin.jsp]
[ XNIO-3 task-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/mesPagesJsps/log4jAdmin.jsp] are [/**]
[ XNIO-3 task-2] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/mesPagesJsps/log4jAdmin.jsp] are {}
[ XNIO-3 task-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/mesPagesJsps/log4jAdmin.jsp] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#1774cad]]] and 1 interceptor
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/mesPagesJsps/log4jAdmin.jsp] is: -1
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : Successfully completed request
[ XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : Successfully completed request
Because I wanted a new path for all jsps (I know we can do that in controller too), and I feared that keep the same servlet for serving both angular frontend and jsp.
Because jhipster generate a lot of class which parameterize (HttpSecurity, ), I though that create a new servlet (without any custom parameters) could be more simple and avoid problems.
DispatcherServlet.render()
--> resolveViewName() qui retourne une JstlView
--> JstlView.render()
--> renderMergedOutputModel()
dispatcherPath = prepareForRendering(request, response); // dispatcherPath = /mesPagesJsps/log4jAdmin.jsp
RequestDispatcher rd = getRequestDispatcher() // rd.path=/mesPagesJsps/log4jAdmin.jsp and rd.servletChain=another DispatcherServlet !!! why ??? named dispatcherServlet, which is not my jsp servlet
--> rd.forward()
--> forwardImpl()
--> response.resetBuffer()
newServletPath = newRequestUri = /mesPagesJsps/log4jAdmin.jsp
pathMatch.servletChain still contains wrond servlet : dispatcherServlet instead of jspServlet
--> servletContext.getDeployment().getServletDispatcher().dispatchToPath(requestImpl.getExchange(), pathMatch, DispatcherType.FORWARD);
--> servletInitialDispatcher.dispatchToPath()
servletRequestContext.servletChain correspond to my servletJSP
--> dispatchRequest( pathInfo = /mesPagesJsps/log4jAdmin.jsp, dispatcherType=FORWARD, servletChain is not my jsp servletJSP but dispatcherServlet )
Exchange is : HttpServerExchange{ GET /mesPagesJsps/log4jAdmin.jsp request {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], Accept-Language=[fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3], Cache-Control=[max-age=0], Accept-Encoding=[gzip, deflate], User-Agent=[Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0], Connection=[keep-alive], Cookie=[CSRF-TOKEN=f6843de6-766d-4259-8a84-242c020420bc; JSESSIONID=VrVa7HNkUmzv_JM_cAhwyrfGWGCcrjZSltoQh2EJ], Upgrade-Insecure-Requests=[1], Host=[localhost:8080]} response {X-Application-Context=[testify_jhi:swagger,dev:8080], Content-Language=[fr-]}}
--> servletInitialHandler.dispatchRequest()
setCurrentServlet( WITH SERVLET dispatcherServlet and NOT servletJSP )
--> next.handleRequest(exchange) : next is here a SessionRestoringHandler
--> next.handleRequest(exchange) : next is here PredicateHandler. This called because a sessionId has been found ...
--> predicate.resolve() with a predicate of type REQUEST (I think this bad) --> which return falseHandler
--> next.handleRequest() --> with again a predicate of type REQUEST --> which return falseHandler
--> next.handleRequest() --> with a ServletDispatchingHandler whose ServletChain is the wrong servlet : dispatcherServlet instead of servletJSP
the dispatcher type is still FORWARD here but its to late because I thing the wrong servlet process the request
Because I wanted a new path for all jsps (I know we can do that in controller too), and I feared that keep the same servlet for serving both angular frontend and jsp.
Because jhipster generate a lot of class which parameterize (HttpSecurity, ), I though that create a new servlet (without any custom parameters) could be more simple and avoid problems.
For example there is HttpSecurity, and this :
public void customize(ConfigurableEmbeddedServletContainer container) {
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
// IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
mappings.add("html", "text/html;charset=utf-8");
// CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
mappings.add("json", "text/html;charset=utf-8");
//mappings.add("jsp", "text/html;charset=utf-8"); // si je fais ça, en combinaisais avec le addResourcesHandler(), alors la page jsp est affichée dans le navigateur
container.setMimeMappings(mappings);
// When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets.
setLocationForStaticAssets(container);
}
I finally found and solve the problem (solution bellow), it seems to have link with some undertow elements, which is not configured by defaut to initialize japser. JasperInitializer was never initialized.
If someone want explain me he is welcome :)
You must add this code in a configuration class.
#Bean
public TomcatContextCustomizer tomcatContextCustomizer() {
return new TomcatContextCustomizer() {
#Override
public void customize(Context context) {
context.addServletContainerInitializer(new JasperInitializer(), null);
}
};
}
#Bean
public TomcatEmbeddedServletContainerFactory tomcatContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setTomcatContextCustomizers(Arrays.asList(new TomcatContextCustomizer[] { tomcatContextCustomizer() }));
return factory;
}
Another question : I have no xml files in my spring boot application, except one :
Is it possible to replace my servlet web application context definition that I build with my WEB-INF/servletJSP-servlet.xml by java/annotation definition ?

Responses with characteristics not acceptable according to the request "accept" headers - HTTP Status 406 - spring-boot

Any takers to resolve this issue for USD50, please contact
I am getting the not acceptable according to the request "accept" headers, however, I believe I have done everything right, I could. Can someone help to resolve this issue. I am using Spring 4.1.
The OBJECTIVE is to be able to return the response in the text/xml format. if I remove produces=text/xml directive then my application works i.e. no error, but the source system treat the response in an unexpected way.
Request coming in as follows:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Cache-Control: no-cache" -H "Postman-Token: 78637a4f-e153-4242-c922-96757d01442a" -d Then values....
My Pom:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.0.rc1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.0.rc1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
My Controller have the following notations:
#RestController
#RequestMapping("/test")
#EnableWebMvcMy Controller has the following notations:
Main Class has the following notation
#Configuration
#EnableAutoConfiguration
#ComponentScan
I DO NOT have the application context xml, as i am using #Autowired
on my end-point method as follows
#RequestMapping(value="/IDEA", headers = {"Accept=*/*"}, produces="text/xml", method= {RequestMethod.POST, RequestMethod.GET})
#Autowired
public MyResult processMyRequest(HttpServletRequest request)
Current Log
2016-08-11 13:38:04.076 INFO 89535 --- [nio-8080-exec-2] c.f.fnocc.injestor.MyController : POST CALLED
2016-08-11 13:38:04.079 INFO 89535 --- [nio-8080-exec-2] c.f.fnocc.injestor.MyController : Request received from ipAddress:0:0:0:0:0:0:0:1
2016-08-11 13:38:04.082 INFO 89535 --- [nio-8080-exec-2] c.f.fnocc.injestor.MyController : REQUEST INFORMATION: [
2016-08-11 13:38:04.084 INFO 89535 --- [nio-8080-exec-2] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#af3b571: startup date [Thu Aug 11 13:38:04 BST 2016]; root of context hierarchy
2016-08-11 13:38:04.095 INFO 89535 --- [nio-8080-exec-2] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2016-08-11 13:38:04.119 INFO 89535 --- [nio-8080-exec-2] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#142abfa2: startup date [Thu Aug 11 13:38:04 BST 2016]; root of context hierarchy
2016-08-11 13:38:04.124 INFO 89535 --- [nio-8080-exec-2] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2016-08-11 13:38:04.150 ERROR 89535 --- [nio-8080-exec-2] c.f.fnocc.injestor.MyController : Error has occurred.
The first issue I see is #EnableWebMvc should be specified on the main class alongside the #Configuration but I don't think it is even needed when you are specifying #EnableAutoConfiguration.
The other issue is the #RequestMapping() has an attribute for consumes which is what you should probably be using instead of looking for the accept header. Reason for that is the accept header normally includes multiple media types not just */* as such the check for equality on that header wouldn't be there.
* Update * I was wrong on the consumes that is used to interpreting the Content-Type header and not the Accept header. Spring tries to match the produces to the Accept header to determine if the method can respond to the incoming request. That makes more sense why you are getting the 406 error as Spring sees the method trying to output text/xml but the request probably doesn't accept that content type in the Accept header.
To further troubleshoot you can setup a request logger to see the specifics on how the request is coming into the service to determine if there is something that is causing Spring to not process it properly. If you add the following bean and enable DEBUG level logging on org.springframework.web.filter.CommonsRequestLoggingFilterthen you can see.
#Bean
public Filter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(false);
filter.setIncludePayload(false);
filter.setIncludeHeaders(true);
return filter;
}
If you can update your question with that request log that would help to troubleshoot.
* Update #2 * Was able to reproduce the error. Adding DEBUG logging level for org.springframework.web showed the issue more clearly.
2016-08-11 02:26:58.242 DEBUG 82904 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/test/IDEA]
2016-08-11 02:26:58.244 DEBUG 82904 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /test/IDEA
2016-08-11 02:26:58.247 DEBUG 82904 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public ca.tuatara.stackoverflow.MyController$MyResult ca.tuatara.stackoverflow.MyController.processMyRequest(javax.servlet.http.HttpServletRequest)]
2016-08-11 02:26:58.247 DEBUG 82904 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/test/IDEA] is: -1
2016-08-11 02:26:58.258 DEBUG 82904 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [public ca.tuatara.stackoverflow.MyController$MyResult ca.tuatara.stackoverflow.MyController.processMyRequest(javax.servlet.http.HttpServletRequest)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
The Could not find acceptable representation is the key. By specifying that you want XML you must include a library to marshall the object as XML as described on the Spring MVC docs. Adding the dependency for:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Made it work for my sample application. Give that a try!

Resources