I have a very strange problem.
I'm trying send request to my SOAP-app, and I get this logs (logging-level=trace):
2022-06-18 12:08:33.341 DEBUG 11612 --- [nio-8080-exec-1] yloadRootAnnotationMethodEndpointMapping : Looking up endpoint for [{localhost/soap}GetAllUser]
2022-06-18 12:08:33.341 DEBUG 11612 --- [nio-8080-exec-1] o.s.w.soap.server.SoapMessageDispatcher : Endpoint mapping [org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping#113c4ad6] maps request to endpoint [public localhost.soap.GetAllUserResponse com.driypeen.userServiceSOAP.endpoint.UserEndpoint.getAllUsers(localhost.soap.GetAllUserRequest)]
Testing endpoint adapter [org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter#1f6f0fe2]
2022-06-18 12:08:33.343 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.dom.DomPayloadMethodProcessor#352c3d70] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.344 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.MessageContextMethodArgumentResolver#4c13ca07] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.344 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.SourcePayloadMethodProcessor#7d17906] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.344 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.XPathParamMethodArgumentResolver#97beeaf] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.345 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.soap.server.endpoint.adapter.method.SoapMethodArgumentResolver#5d68954d] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.345 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.soap.server.endpoint.adapter.method.SoapHeaderElementMethodArgumentResolver#f793f15] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.345 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.jaxb.XmlRootElementPayloadMethodProcessor#3ec7eb5] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.351 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.jaxb.JaxbElementPayloadMethodProcessor#5534e6f1] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.352 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.dom.JDomPayloadMethodProcessor#4c6fc3e7] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.352 TRACE 11612 --- [nio-8080-exec-1] o.s.w.s.e.a.DefaultMethodEndpointAdapter : Testing if argument resolver [org.springframework.ws.server.endpoint.adapter.method.StaxPayloadMethodArgumentResolver#aa8dce8] supports [class localhost.soap.GetAllUserRequest]
2022-06-18 12:08:33.353 DEBUG 11612 --- [nio-8080-exec-1] o.s.w.soap.server.SoapMessageDispatcher : Testing endpoint adapter [org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter#ab2009f]
2022-06-18 12:08:33.353 DEBUG 11612 --- [nio-8080-exec-1] s.e.SoapFaultAnnotationExceptionResolver : Resolving exception from endpoint [public localhost.soap.GetAllUserResponse com.driypeen.userServiceSOAP.endpoint.UserEndpoint.getAllUsers(localhost.soap.GetAllUserRequest)]: java.lang.IllegalStateException: No adapter for endpoint [public localhost.soap.GetAllUserResponse com.driypeen.userServiceSOAP.endpoint.UserEndpoint.getAllUsers(localhost.soap.GetAllUserRequest)]: Is your endpoint annotated with #Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?
2022-06-18 12:08:33.354 DEBUG 11612 --- [nio-8080-exec-1] o.s.w.s.s.e.SimpleSoapExceptionResolver : Resolving exception from endpoint [public localhost.soap.GetAllUserResponse com.driypeen.userServiceSOAP.endpoint.UserEndpoint.getAllUsers(localhost.soap.GetAllUserRequest)]: java.lang.IllegalStateException: No adapter for endpoint [public localhost.soap.GetAllUserResponse com.driypeen.userServiceSOAP.endpoint.UserEndpoint.getAllUsers(localhost.soap.GetAllUserRequest)]: Is your endpoint annotated with #Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?
2022-06-18 12:08:33.370 DEBUG 11612 --- [nio-8080-exec-1] o.s.w.soap.server.SoapMessageDispatcher : Endpoint invocation resulted in exception - responding with Fault
It turns out that the server finds the endpoint, but does not find the adapter?
So, i written this:
#Autowired
List<EndpointAdapter> adapters;
#PostConstruct
public void a () {
log.info("ADAPTERS:");
adapters.forEach(System.out::println);
}
And get this output:
2022-06-18 12:07:03.106 INFO 11612 --- [ main] c.d.u.endpoint.UserEndpoint : ADAPTERS:
org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter#1f6f0fe2
org.springframework.ws.server.endpoint.adapter.PayloadEndpointAdapter#ab2009f
My XSD file contains this:
<xs:element name="GetAllUserRequest">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetAllUserResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="users" type="tns:UserWithoutRole" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Generated classes look like this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(
name = ""
)
#XmlRootElement(
name = "GetAllUserRequest"
)
public class GetAllUserRequest {
public GetAllUserRequest() {
}
}
My request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:gs="localhost/soap">
<soapenv:Header/>
<soapenv:Body>
<gs:GetAllUser/>
</soapenv:Body>
</soapenv:Envelope>
Endpoint class:
#Endpoint
#Slf4j
public class UserEndpoint {
private static final String NAMESPACE_URI = "localhost/soap";
private UserService userService;
#Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
#Autowired
List<EndpointAdapter> adapters;
#PostConstruct
public void a () {
log.info("ADAPTERS:");
adapters.forEach(System.out::println);
}
#PayloadRoot(localPart = "GetAllUser", namespace = NAMESPACE_URI)
#ResponsePayload
public GetAllUserResponse getAllUsers(#RequestPayload GetAllUserRequest request) {
log.info("GET ALL USERS");
GetAllUserResponse response = new GetAllUserResponse();
response.getUsers().addAll(userService.findAll());
return response;
}
}
WebServiceConfig:
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "soap")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("SoapPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("localhost/soap");
wsdl11Definition.setSchema(countriesSchema);
return wsdl11Definition;
}
#Bean
public XsdSchema countriesSchema() {
return new SimpleXsdSchema(new ClassPathResource("userServiceSOAP.xsd"));
}
#Bean
public EndpointAdapter messageEndpointAdapter() {
return new PayloadEndpointAdapter();
}
}
Why does none of the adapters support my endpoint?
Thanks!
I faced the same issue. In my case it was related to using Jakarta XML bind.
When I change it to Javax instead of Jakarta everything works fine.
So when you check imports in your generated sources, it should be smth like that:
import javax.xml.bind.annotation.XmlRootElement;
Additional dependencies for Java 8+ listed below:
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.activation/activation -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
Note if your Java version is 8 or less, this guide works fine w/o changes, because Java 8 is still shipped with JAXB implementation.
I saw that Spring 5 doesn't support Jakarta, they planned to add support in future 6 version.
I am trying to implement simple demo MVC app with Spring Boot but I get 404 error while executing the application. The uri is `http://localhost:8080/' which is to display all the rows in a table called circle.
Spring Boot : 1.3.3.RELEASE
Java Version : 1.8.0_65
Database : Apache Derby 10.12.1.1
Maven Java Project:
Application.java
package com.nomad.dubbed.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
CircleController.java
package com.nomad.dubbed.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.nomad.dubbed.dao.CircleService;
import com.nomad.dubbed.model.Circle;
#RestController
#RequestMapping("/")
public class CircleController {
#Autowired
private CircleService circleService;
#RequestMapping(method=RequestMethod.GET)
public List<Circle> getAll() {
return circleService.getAll();
}
}
CircleRepository.java
package com.nomad.dubbed.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.nomad.dubbed.model.Circle;
#Repository
public interface CircleRepository extends JpaRepository<Circle, Integer> {
}
CircleService.java
package com.nomad.dubbed.dao;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.nomad.dubbed.model.Circle;
#Service
public class CircleService {
#Autowired
private CircleRepository circleRepository;
#Transactional(propagation=Propagation.REQUIRED)
public List<Circle> getAll(){
return circleRepository.findAll();
}
}
Circle.java
package com.nomad.dubbed.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="circle")
public class Circle {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
public Circle(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
application.properties
spring.datasource.url=jdbc:derby://localhost:1527/db
spring.datasource.driverClassName=org.apache.derby.jdbc.ClientDriver
logging.level.org.springframework.web:DEBUG
logging.level.org.hibernate:DEBUG
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>com.nomad.dubbed</groupId>
<artifactId>spring-boot-mvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<derby-client.version>10.11.1.1</derby-client.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>${derby-client.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>spring-boot-mvc</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Database is up and running, there are 5 rows in the table circle:
The default uri (/beans, /health..) works fine but the implemented controller is not recognized. There is no error of such displayed in the console, below is the dump of logs printed in console after I send the request.
2016-05-03 14:17:26.594 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/]
2016-05-03 14:17:26.596 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /
2016-05-03 14:17:26.596 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/]
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/] are [/**]
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/] are {}
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/] 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#6c13019c]]] and 1 interceptor
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/] is: -1
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Successfully completed request
2016-05-03 14:17:26.597 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2016-05-03 14:17:26.600 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2016-05-03 14:17:26.600 DEBUG 659 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
2016-05-03 14:17:26.600 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html])
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#2f5f8d71] based on requested media type 'text/html'
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#2f5f8d71] in DispatcherServlet with name 'dispatcherServlet'
2016-05-03 14:17:26.601 DEBUG 659 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Successfully completed request
use a different url for your controller. "/" in spring-boot maps to static resources located in META-INF/resources and src/main/resources/static/ .
edit: forget above and do the following in your application class:
Application.java
package com.nomad.dubbed.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#ComponentScan("com.nomad.dubbed")
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
your rest controller is not discovered by spring-boots component scan. according to this doc http://docs.spring.io/spring-boot/docs/current/reference/html/… spring scans the packages below the package where the class with the #SpringBootApplication annotation resides. your controller is located in a parallel package.
We should not use #ComponentScan annotation with #SpringBootApplication, as that's not the right practice.
#SpringBootApplication is a combination of 3 annotations: #ComponentScan, #EnableAutoConfiguration and #Configuration.
Main class which has the #SpringBootApplication annotation should be in parent/super package.
e.g. - com.spring.learning is a parent package and its children are
com.spring.learning.controller, com.spring.learning.service, com.spring.learning.pojo
Hence it scans its package and sub packages.
This is the best practice – project layout or structure is a prominent concept in Spring Boot.
This what happens behind.
#SpringBootApplication annotation is a combination of #Configuration #EnableAutoConfiguration #ComponentScan.
#ComponentScan without arguments tells the framework to find components/beans in the same package and its sub-packages.
Your Application class which is annotated with #SpringBootApplication is in the package com.nomad.dubbed.app. So it scans that package and its sub-packages under it (like com.nomad.dubbed.app.*). But your CircleController is inside package com.nomad.dubbed.controller which is not scanned by default. Your repositories too fall outside the default scan packages, so they too will not be discovered by spring framework.
So what to do now?, you have two options.
Option 1
Move the Application class to the top directory(package). In your case com.nomad.dubbed package. Then, since all controllers and other repositories are in sub-packages, they will be discovered by the framework.
Option 2
Use #ComponentScan annotation with basePackages argument, along with the #SpringBootApplication in your Application class like below.
#SpringBootApplication
#ComponentScan(basePackages="com.nomad.dubbed")
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
please check that the your controller classes are in sub packages.
For example, if the main class is com.myapp package, then controller class is either in the same package or is in sub package like com.myapp.controllers. Spring Framework will scan root package and then all its sub packages. In this case things will just work and you would not need to use #ComponentScan.
If you place the main class in com.myapp and other beans/controllers which you want to be autowired you place in a different package like com.beans which is not a sub package of com.myapp, then you will experience an issue when beans could not be found.
Thanks!
Bageeradha
I have to research more why spring - boot failed to recognize controller with the original package structure. I dumped all the java classes into one package and finally got the demo project running.
Modified Java Project Structure:
The CircleController.java class was also modified. I have all the records deleted from the circle table without mentioning specific Request Method, method=RequestMethod.GET.
package com.nomad.dubbed.app;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class CircleController {
#Autowired
private CircleService circleService;
#RequestMapping(value="/circles", method=RequestMethod.GET)
public List<Circle> getAll() {
return circleService.getAll();
}
}
I had the same problem and I added #ComponentScan(basePackages = "package.name") in the Application class. After that my rest controller was recognized.
package com.nomad.dubbed.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#ComponentScan(basePackages = "com.spring.basepkg")
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
Could you try adding the #ResponseBody Annotation
#RequestMapping(method=RequestMethod.GET)
#ResponseBody
public List<Circle> getAll() {
return circleService.getAll();
}
In my opinion, this visibility problem comes when we leave the component scan to Spring which has a particular way of looking for the classes using standard convention. In this scenario as the Starter class(Application)is in com.nomad.dubbed.app package, putting Controller one level below will help Spring to find the classes using the default component scan mechanism. Putting CircleController under com.nomad.dubbed.app.controller should solve the issue.
I had a similar issue. Adding the annotation #SpringBootApplication(scanBasePackages={"com.nomad.dubbed"}) on the Application class worked for me.
actually springboots scans all of its components under you core package like example:
package com.nomad.dubbed.app;
if you add controllers, services, dao packages under com.nomad.dubbed.app.controllers, com.nomad.dubbed.app.services, com.nomad.dubbed.app.dao.
then you can easily run your rest controller, but if you add all packages parallel to your core springboot package like com.nomad.dubbed.controllers, com.nomad.dubbed.services.
then you need to scan for #ComponentScan({"com.nomad.dubbed.controllers","com.nomad.dubbed.services"})
if you choose to go for componentscan then you have to also scan for springboot application package as well.
so best way is create all the packages under spring boot application dubbed.app.xyz...
The issue is Spring boot scans the package where the file with main method is located.
In my case: demo.example package. So, the controllers should be created inside this package only to be scanned.
When the main file was under com.example.demo package, it was not identifying StudentController.
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"})
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.
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
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>