How can I disable the DispatcherServlet on SpringBoot, even trying to disable it via servlet registration the uri mapping appears on the log:
#Bean
public ServletRegistrationBean servletRegistrationBean(final DispatcherServlet dispatcherServlet) {
final ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet);
servletRegistrationBean.setEnabled(false);
return servletRegistrationBean;
}
LOG
2015-06-10 10:39:57.552 INFO 7032 --- [ main] o.s.b.c.e.ServletRegistrationBean : Servlet dispatcherServlet was not registered (disabled)
2015-06-10 10:39:57.553 INFO 7032 --- [ main] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
Thanks any help!
I added below code into my main class, and the servlet was removed from log.
#SpringBootApplication(exclude = { DispatcherServletAutoConfiguration.class })
From Spring boot docs here
Spring Boot wants to serve all content from the root of your application / down. If you would rather map your own servlet to that URL you can do it, but of course you may lose some of the other Boot MVC features. To add your own servlet and map it to the root resource just declare a #Bean of type Servlet and give it the special bean name dispatcherServlet (You can also create a bean of a different type with that name if you want to switch it off and not replace it).
If you exclude DispatcherServletAutoConfiguration.class,
then you need to exclude ErrorMvcAutoConfiguration.class as well, or at least I did.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
#SpringBootApplication(exclude = { DispatcherServletAutoConfiguration.class, ErrorMvcAutoConfiguration.class})
#EnableAspectJAutoProxy
public class CoreApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(CoreApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CoreApplication.class);
}
}
Related
I am working with spring boot tutorial from javabrains and everything was clear until putting CrudRepository inside project. Below you can find my main class:
package pl.springBootStarter.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class CourseApiDataApplication
{
public static void main(String args[])
{
SpringApplication.run(CourseApiDataApplication.class,args);
}
}
Service class:
package pl.springBootStarter.app.topic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
#Service
public class TopicService
{
#Autowired
private TopicRepository topicRepository;
private List<Topic> topics = new ArrayList<>(Arrays.asList(
new Topic("spring","spring framework", "spring framework dectription"),
new Topic("sprin","spring framework", "spring framework dectription"),
new Topic("spri","spring framework", "spring framework dectription")));
public List<Topic> getAllTopics()
{
// return topics;
List<Topic> t = new ArrayList<Topic>();
topicRepository.findAll().forEach(t::add);
return t;
}
public Topic getTopic (String id)
{
return topics.stream().filter( t -> t.getId().equals(id)).findFirst().get();
}
public void addTopic(Topic topic) {
topicRepository.save(topic);
}
public void updateTopic(Topic topic, String id)
{
topics.set(topics.indexOf(topics.stream().filter(t-> t.getId().equals(id)).findFirst().get()), topic);
}
public void deleteTopic(String id)
{
topics.remove(topics.stream().filter(t -> t.getId().equals(id)).findFirst().get());
}
}
And Repository interface:
package pl.springBootStarter.app.topic;
import org.springframework.data.repository.CrudRepository;
public interface TopicRepository extends CrudRepository<Topic,String>
{
}
When I run the app there is a problem with injection of TopicRepository into topicRepository field in TopicService class. I get following error:
Error starting ApplicationContext. To display the conditions report re- run your application with 'debug' enabled.
2019-05-01 10:33:52.206 ERROR 6972 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field topicRepository in pl.springBootStarter.app.topic.TopicService required a bean of type 'pl.springBootStarter.app.topic.TopicRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
What could be the reason that Spring cannot do the autowiring?
Be sure the class is scanned by spring!
(this may help if that's the problem:
Intellij Springboot problems on startup).
Optionally you may want to annotate TopicRepository as a #Repository.
#Repository
public interface TopicRepository extends CrudRepository<Topic,String>
{
}
See a demo code here: https://github.com/lealceldeiro/repository-demo
Spring cannot inject bean because it has not been created.
You have to instruct Spring to generate implementation of declared repository interfaces by using #EnableJpaRepositories(basePackages={"pl.springBootStarter.app"}) annotation on any of your configuration classes or class annotated with #SpringBootApplication. That should fix your problem.
I got a similar message and I was missing the #Service annotation in the Service class. Simple mistake, posting in case it helps anyone else.
For anybody who was brought here by googling the generic bean error message, but who is actually trying to add a feign client to their Spring Boot application via the #FeignClient annotation on your client interface, none of the above solutions will work for you.
To fix the problem, you need to add the #EnableFeignClients annotation to your Application class, like so:
#SpringBootApplication
// ... (other pre-existing annotations) ...
#EnableFeignClients // <------- THE IMPORTANT ONE
public class Application {
I got a similar message.
the thing was my main package was com.example
and the package for other classes was com.xyz
so when I Changed the name of the package of other class to com.example.topic
i.e.
finally
The main package was com.example
and the package for the other class was com.example.topic
A simple mistake, posting in case it helps anyone else.
In my cases, the necessary configuration from org.springframework.boot.autoconfigure.jdbc. has been excluded at SpringBootApplication, causing relevant bean not added properly. Check your main application java file and see if you can find following configuration in the exclusion list
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
#SpringBootApplication(
exclude = {
DataSourceAutoConfiguration.class, // REMOVE THIS
DataSourceTransactionManagerAutoConfiguration.class, // REMOVE THIS
}
)
and remove them from exclusion list.
in service class
do:
#Autowired(required=false)
I just wrote a Springboot application as a testing Webserver which origins from spring.io.
It packaged initially in "jar", changed it to "war" file.
And get the application class code as below:
package com.ronzhong;
import org.springframework.boot.Banner.Mode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.context.WebApplicationContext;
#SpringBootApplication(scanBasePackages={"com.ronzhong.libraryManagement"})
public class LibraryManagementApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
application.application().setBannerMode(Mode.OFF);
return application.sources(SpringApplicationBuilder.class);
}
protected WebApplicationContext run(SpringApplication application) {
return (WebApplicationContext) application.run();
}
// public static void main(String[] args) {
// SpringApplication.run(LibraryManagementApplication.class, args);
//}
}
and the controller is :
package com.ronzhong.libraryManagement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.*;
//#CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
#RestController
#RequestMapping("/api")
public class CounterController {
#Autowired
private BookService bookService;
#PostMapping
public boolean add(#RequestBody Book book){
return bookService.add(book);
}
#RequestMapping(value = "/books", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Book[] get(){
return bookService.getBooks();
}
#RequestMapping(value = "{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Book findOne(#PathVariable("id") int id){
return bookService.findById(id);
}
}
And I also checked the
"Dynamic Web Module" in the project facets.
Finally, I got these logs when launch tomcat server with this war file generated.
INFO: 2 Spring WebApplicationInitializers detected on classpath
2018-11-28 10:43:31.925 INFO 14888 --- [ main] c.ronzhong.LibraryManagementApplication : Starting LibraryManagementApplication on ronzhongmachine with PID 14888 (C:\Users\ronzhong\workspace_testserver\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\library-Management\WEB-INF\classes started by ronzhong in C:\tools_installers\eclipse-jee-2018-09-win32-x86_64\eclipse)
2018-11-28 10:43:32.002 INFO 14888 --- [ main] c.ronzhong.LibraryManagementApplication : No active profile set, falling back to default profiles: default
2018-11-28 10:43:33.910 INFO 14888 --- [ main] o.a.c.c.C.[.[.[/library-Management] : Initializing Spring embedded WebApplicationContext
2018-11-28 10:43:33.911 INFO 14888 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1604 ms
2018-11-28 10:43:34.362 INFO 14888 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'errorPageFilter' to: [/*]
2018-11-28 10:43:34.704 INFO 14888 --- [ main] c.ronzhong.LibraryManagementApplication : Started LibraryManagementApplication in 5.958 seconds (JVM running for 36.407)
2018-11-28 10:43:34.955 INFO 14888 --- [ main] org.apache.coyote.ajp.AjpNioProtocol : Starting ProtocolHandler ["ajp-nio-8009"]
2018-11-28 10:43:34.968 INFO 14888 --- [ main] org.apache.catalina.startup.Catalina : Server startup in 28177 ms
There're no mappings info in the logs.
And if I request with http://localhost:8080/api/books, it will get 404 error.
But the logs hasn't change even a little.
So I googled the potential causes, and excluded those causes temporarily:
springboot application does not scan the package which controller locates?
I moved springboot application class to the uplevel package, and also specified what kind of package it should scan.
While you see, it doesn't work.
the annotation issue?
Some people say we should use #RestController annotation instead of #Controller, better add the #ResponseBody, while I did.
it does't work, either.
the deployment issue?
don't know, I did changed the build path of this project, which generated jar file and war file normally, but webapp folder is empty, since I don't have any static resource, I think it's fine, right?
Anyone can help me? very appreciate for your answer, thanks in advance.
From the logs, I can see that your war file name is library-Management, whichh means its deloyed under this folder, as logs states. So you should check http://localhost:8080/library-Management/api/books instead.
You get 404 from Tomcat, it doesnt hit your app at all, this is ehy you dont see any logs.
I am trying to test the access of one of my #RestController which is secured by a custom Spring Security configuration. My use case is the following: A HTTP GET to /someEndpoint is secured with authentification, but a HTTP POST request to the same endpoint is not secured. It's working fine when I boot application and test it with my frontend or Postman.
Now I am trying to write tests with MockMvc with the security configuration. I already made it through a lot of answers on StackOverflow, but nothing helped me.
My test setup looks like the following:
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = MyController.class)
#WebAppConfiguration
#ContextConfiguration
public class AssessmentControllerTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#Before
public void init() throws Exception {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.alwaysDo(print())
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}
// some test methods
}
With this setup all my endpoints are secured and even a HTTP POST is returning a 401 instead of 201. I also enabled the debug log for security and in the debug logs it says that the test uses the default configure(HttpSecurity) and I can't find any of my AntMatchers in the logs:
2018-07-04 19:20:02.829 DEBUG 2237 --- [ main] s.s.c.a.w.c.WebSecurityConfigurerAdapter : Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).
2018-07-04 19:20:03.097 DEBUG 2237 --- [ main] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'authenticated', for org.springframework.security.web.util.matcher.AnyRequestMatcher#1
2018-07-04 19:20:03.127 DEBUG 2237 --- [ main] o.s.s.w.a.i.FilterSecurityInterceptor : Validated configuration attributes
2018-07-04 19:20:03.130 DEBUG 2237 --- [ main] o.s.s.w.a.i.FilterSecurityInterceptor : Validated configuration attributes
2018-07-04 19:20:03.161 INFO 2237 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher#1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#5a75ec37, org.springframework.security.web.context.SecurityContextPersistenceFilter#3f736a16, org.springframework.security.web.header.HeaderWriterFilter#529c2a9a, org.springframework.security.web.csrf.CsrfFilter#7f93dd4e, org.springframework.security.web.authentication.logout.LogoutFilter#707b1a44, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#26c89563, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter#1e0a864d, org.springframework.security.web.authentication.www.BasicAuthenticationFilter#22ebccb9, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#53abfc07, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#4aa21f9d, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#2c05ff9d, org.springframework.security.web.session.SessionManagementFilter#26bbe604, org.springframework.security.web.access.ExceptionTranslationFilter#4375b013, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#a96d56c]
2018-07-04 19:20:03.236 INFO 2237 --- [ main] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring FrameworkServlet ''
2018-07-04 19:20:03.237 INFO 2237 --- [ main] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization started
Is it in general possible to use my concrete Spring Security configuration during a MockMvc test or do I have to boot the whole Spring context during the test with #SpringBootTest ? I am using (Spring Boot 2.0.3.RELEASE with Java 1.8)
Thanks in advance!
With the spring-boot 2.x it is not possible to switch of security with a property anymore. You have to write an own SecurityConfiguration which has to be added to your test context. This security config should allow any request without authentication.
#Configuration
#EnableWebSecurity
public class TestSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception{
web.debug(true);
}
}
test class annotation:
#ContextConfiguration(classes = { ..., TestSecurityConfiguration.class })
public class MyTests {...
I have created a Spring Boot application. I have configured my class that contains the scheduler method startService().
Below is my code :
Service Class :
package com.mk.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.mk.envers.model.BossExtChange;
import com.mk.envers.model.BossExtChangeRepository;
#Component
public class EnverseDemoService {
#Autowired
BossExtChangeRepository bossExtChangeRepository;
#Scheduled(fixedRate = 30000)
public void startService() {
System.out.println("Calling startService()");
BossExtChange bossExtChange = bossExtChangeRepository.findById(5256868L);
System.out.println("bossExtChange.getDescription()--->"+bossExtChange.getDescription());
System.out.println("Ending startService()");
}
}
Main Class :
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableScheduling;
#SpringBootApplication
#EnableScheduling
#PropertySource("classpath:application.properties")
public class EnverseDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EnverseDemoApplication.class, args);
}
}
I have annotated the class as #Component and also method as #Scheduled(fixedRate = 30000) that will running as a scheduler. But while running the application as Spring Boot the scheduler does not trigger. The console show the below message:
2016-02-03 10:56:47.708 INFO 10136 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-02-03 10:56:47.721 INFO 10136 --- [ main] com.mk.envers.EnverseDemoApplication : Started EnverseDemoApplication in 3.231 seconds (JVM running for 3.623)
2016-02-03 10:56:47.721 INFO 10136 --- [ Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#49e202ad: startup date [Wed Feb 03 10:56:44 IST 2016]; root of context hierarchy
2016-02-03 10:56:47.721 INFO 10136 --- [ Thread-2] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
2016-02-03 10:56:47.736 INFO 10136 --- [ Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
Can anyone please help me out.
May be you can solve this problem by adding the #ComponentScan annotation in the configuration file
#SpringBootApplication
#EnableScheduling
#ComponentScan(basePackages = "com.mk.service")
#PropertySource("classpath:application.properties")
public class EnverseDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EnverseDemoApplication.class, args);
}
}
I was able to solve the issue, I forgot to provide #service level annotation,
I have created the check List for #Scheduler, kindly go through every point one by one, It will help you to solve the issue.
Check for the #EnableScheduling on SpringBoot Main class.
Scheduled method should be annotated with #Scheduled, Follow the #Scheduled Method rules. a method should have the void return type, a method should not accept any parameters.
Make sure the class should be annotated with #Service or #Component Annotation so SpringBoot can make the object of that class.
The package of the scheduler jobs should be under the main Application class's package. e.g com.company is your main application class package then scheduler class package should be com.company.scheduler,
If you are using Cron expression confirm the same e.g #Scheduled( cron = "0 0/2 * * * ?"), This Cron expression will schedule the task for every 2 min.
Feel free to add more points in the comment so it will help to solve the issue.
It must be that you forgot to add #EnableScheduling annotation in your app class.
public static void main(String[] args) {
context = SpringApplication.run(YouApplication.class, args);
}
I was finally able to solve the above issue, I changed the package of my service class EnverseDemoService from package com.mk.service; to com.mk.envers.service;. This is because if the main configuration class EnverseDemoApplication is present in the package com.mk.envers. All the other classes in the boot application should be in the qualifying package. Eg: com.mk.envers.*;
In my case, was the lazy-initialization with value true which was preventing my #Component to be loaded by Spring at startup and #Scheduled method was never running.
Make sure the Spring Boot lazy initialization is disabled.
Please check if in application.properties you have
"spring.main.lazy-initialization=true"
Remove this from application.properties.
Even if you have all the configuration correct, this simple line will enable lazy loading due to which your #Component will initalize during application start.
As Swapnil already mentioned all the check-points to make sure while using cron. One additional thing you should do:
Always verify your cron expression whether it's in right format or not, using below reference site - http://www.freeformatter.com/cron-expression-generator-quartz.html#
I'm currently using an index.html in my public folder. It was displaying correctly, then somewhere along development, the routing broke and now
http://localhost:8080/ shows:
{
"_links" : {
"users" : {
"href" : "http://localhost:8080/users"
},
"profile" : {
"href" : "http://localhost:8080/alps"
}
}
}
instead of my index.html. Strangely enough the users link returns a json list of my users table.
How do I revert back to my index.html page?
Application.java
package com.exp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
#SpringBootApplication
#EnableAutoConfiguration(exclude = { JacksonAutoConfiguration.class })
#EnableAsync
#EnableScheduling
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Obviously you have added Spring Data REST as dependency, which produces this output. However, it should only show this, if you use the Accept header with application/json in your request which shouldn't be the case for a regular browser.
One solution would be to remove this dependency.
The other solution would be, that you change the base path for Spring Data REST, so you can distinguish it from the other resources in your application. For that, add the following property to your application.properties:
spring.data.rest.base-uri=/yourbasepath
I had an empty folder src/main/webapp that was being picked up before public/. Could have possibly been created when I changed my spring boot packaging from jar to war.
deleting the webapp folder, or shifting files from public to webapp solves the issue.