Spring configuration without Spring Boot - java

I've been trying to configure Spring without Spring Boot.
I added a Tomcat, created the MainController class, and configured the Dispatcher Servlet
but in an endpoint 'http://localhost:8080/main/hello I receive 404.
I think it is problem in the ServletDispatcherConfig.
This is my  ServletDispatcherConfig  class
#Component
public class ServletDispatcherConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {SpringConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
and this is my SpringConfig class
#Configuration
#ComponentScan("example.test")
#EnableWebMvc
public class SpringConfig {
private final ApplicationContext applicationContext;
#Autowired
public SpringConfig(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
var resolver = new SpringResourceTemplateResolver();
resolver.setCacheable(true);
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setApplicationContext(applicationContext);
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
var engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.setEnableSpringELCompiler(true); // delete if any bugs will be
return engine;
}
#Bean
public ThymeleafViewResolver viewResolver() {
var templateResolver = new ThymeleafViewResolver();
templateResolver.setTemplateEngine(templateEngine());
return templateResolver;
}
}
my MainController class
#Controller
#RequestMapping("/main")
public class MainController {
#GetMapping("/first")
public String main() {
return "/main";
}
#GetMapping("/hello")
public String hello() {
return "/main";
}
}

Related

Did ComponentScan work in my SpringMVCproject?

I have a project based on SpringMVC 5 and an error happened when I tried to run it on JBoss EAP 7.3.
14:33:14,134 DEBUG
[org.springframework.beans.factory.support.DefaultListableBeanFactory]
(ServerService Thread Pool -- 99) Creating shared instance of
singleton bean 'userDetailsService'
14:33:14,140 ERROR [org.springframework.web.context.ContextLoader]
(ServerService Thread Pool -- 99) Context initialization failed:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'springSecurityFilterChain' defined in
org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration:
Bean instantiation via factory method failed;......nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.aaa.bbb.security.service.UserService'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
Here's the code of class "UserDetailsServiceImpl":
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserService userService;
#Autowired
private SessionUtils sessionUtils;
#Override
public UserDetails loadUserByUsername(String userID) throws UsernameNotFoundException {
User user = userService.get(userID);
if (user == null) throw new UsernameNotFoundException("Could not find user");
sessionUtils.expireUserSessions(user.getUser_name()); // Force expire other session
return new UserDetailsInfo(user);
}
}
And here's the code of class "UserService":
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
public User get(String id) {
return userRepository.findById(id).get();
}
public User getuUserByUsername(String user_name) {
return userRepository.getuUserByUsername(user_name);
}
public int incLoginErrorCount(String id) {
return userRepository.incLoginErrorCount(id);
}
public int resetLoginErrorCount(String id) {
return userRepository.resetLoginErrorCount(id);
}
public int lockCount(String id) {
return userRepository.lockCount(id);
}
public int changeUPassword(String id, String password) {
return userRepository.changeUPassword(id, password);
}
}
And I'm using "WebAppInitializer":
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
private String TMP_FOLDER = "/tmp";
private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024;
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { WebSecurityConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebMvcConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter(), new MultipartFilter(),
new OpenEntityManagerInViewFilter() };
}
#Override
protected void registerDispatcherServlet(ServletContext servletContext) {
super.registerDispatcherServlet(servletContext);
servletContext.addListener(new HttpSessionEventPublisher());
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER, MAX_UPLOAD_SIZE,
MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
registration.setMultipartConfig(multipartConfigElement);
}
}
To call "WebMvcConfig":
#ComponentScan(basePackages = {"com.aaa.bbb"})
public class WebMvcConfig implements WebMvcConfigurer {
#Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(100000);
return multipartResolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**", "/resources/**", "/resources/**", "/webjars/**", "/log/**")
.addResourceLocations("classpath:/css/", "classpath:/js/", "classpath:/json/", "/webjars/", "/META-INF/");
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("message/messages");
source.setUseCodeAsDefaultMessage(true);
source.setDefaultEncoding("UTF-8");
return source;
}
}
If #ComponentScan worked, this error should not happen.
Thank you!
I think you should use #Service annotation on the UserDetailsServiceImpl class too. Since it is not annotated, componentScan doesn't know that it should autowire the services inside it. So UserDetailsServiceImpl class should look like this.
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserService userService;
#Autowired
private SessionUtils sessionUtils;
#Override
public UserDetails loadUserByUsername(String userID) throws UsernameNotFoundException {
User user = userService.get(userID);
if (user == null) throw new UsernameNotFoundException("Could not find user");
sessionUtils.expireUserSessions(user.getUser_name()); // Force expire other session
return new UserDetailsInfo(user);
}
}

Failed to register servlet with name 'dispatcher'.Check if there is another servlet registered under the same name.

What is wrong in below Java code and what does it mean? Can anyone please help me to solve this:
java.lang.IllegalArgumentException: Failed to register servlet with name 'dispatcher'.Check if there is another servlet registered under the same name.
AppConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.kk.kk.config")
public class AppConfig {
//Define a bean for ViewResolver
#Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
DispatcherServletInitializer.java
public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
//TODO Auto-generated method stub
return null;
}
#Override
protected Class<?>[] getServletConfigClasses(){
return new Class[] {AppConfig.class};
}
#Override
protected String[] getServletMappings(){
return new String[] {"/"};
}
}
AppController.java
#Controller
public class AppController {
#GetMapping("/")
public String showHome(){
return "home";
}
}
You can implement WebMvcConfigurer :
Try this:
#Configuration
#EnableWebMvc
public class AppConfig implements WebMvcConfigurer{
}

I can not Inject Spring Beans into Test using TestNG launcher (Multithreading)

#TransactionConfiguration
#Transactional
#ContextConfiguration(classes=AnnotationConfigContextLoaderUtils.class)
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
public class AnyTest extends TestMachine {
#Inject
private AccountDao accDao; //ALLWAYS NULL
I run the test with:
TestNG testNG = new TestNG();
AppConfig.java
#Bean
public SessionScope sessionScope(){
return new SessionScope();
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public JdbcTemplate jdbcTemplate() throws ConfigurationException {
return new JdbcTemplate(dataSource());
}
#Bean
public DataSource dataSource() throws ConfigurationException {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
//DB INITIALIZE
}
#Bean(name = "sessionFactory")
public LocalSessionFactoryBean sessionFactory() throws ConfigurationException {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan("package.model");
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
#Bean
public HibernateTransactionManager transactionManager() throws ConfigurationException {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put("hibernate.hbm2ddl.auto", hibernateAuto);
properties.put("hibernate.dialect", hibernateDialect);
properties.put("hibernate.show_sql", showSQL);
return properties;
}
SpringMVCInitializer.java
public class SpringMVCInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {AppConfig.class, SpringMVCConfiguration.class, SimpleCORSFilter.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
Maven dependency versions:
<spring-version>4.0.3.RELEASE</spring-version>
<spring-test>4.0.3.RELEASE</spring-test>
<testNG-Version>6.9.4</testNG-Version>
<hibernate.version>4.1.5.Final</hibernate.version>
<hibernate-validator>4.2.0.Final</hibernate-validator>
<mysql.connector.version>5.1.32</mysql.connector.version>
<dbcp.version>1.4</dbcp.version>
Why I can't inject any bean to a test?
Note: I used #Autowired and it did not work too.
One sugestion is inject the session in the main method I used to run the test.
Is any way to make this?
I resolved this problem creating a Static Class and injecting the dependencies into this class in a controller.
Controller:
#Controller
public class InitController {
#Inject
public InitController(TestDao testDao, InsynctivePropertyDao propertyDao, ServletContext servletContext, AccountDao accDao, CrossBrowserAccountDao crossDao, CreatePersonFormDao createPersonFormDao, TestSuiteDao testSuiteDao) {
HibernateUtil.init(testDao, propertyDao, servletContext, accDao, crossDao, createPersonFormDao, testSuiteDao);
}
}
HibernateUtil.java
public class HibernateUtil {
public static CrossBrowserAccountDao crossDao;
public static TestDao testDao;
public static synchronized void init(TestDao testDao, InsynctivePropertyDao propertyDao, ServletContext servletContext, AccountDao accDao, CrossBrowserAccountDao crossDao, CreatePersonFormDao createPersonFormDao, TestSuiteDao testSuiteDao){
HibernateUtil.crossDao = crossDao;
HibernateUtil.testDao = testDao;
}
}

Use #Autowired in Spring MVC and JavaConfig

I have spring mvc project and i don't use #Autowired because my object always is null. How me load JavaConfig for using #Autowired, i do not use any *.xml file.
This is my controller with #Autowired field for service.
#Controller
public class WebController {
#Autowired
private ServiceWeb serviceWeb;
public void setServiceWeb(ServiceWeb serviceWeb) {
this.serviceWeb = serviceWeb;
}
...
}
This is my AbstractAnnotationConfigDispatcherServletInitializer
public class ServletInit extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SpringRootConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringWebConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
SpringRootConfig & SpringWebConfig
#Configuration
#ComponentScan({"web.controller"})
public class SpringRootConfig {
}
#EnableWebMvc
#Configuration
#ComponentScan({ "web.controller"})
#Import({SecurityConfig.class})
public class SpringWebConfig extends WebMvcConfigurerAdapter{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
Class for #Autowiring
#Configuration
public class ConfigurationBean {
#Bean
public ServiceWeb serviceWeb(){
return new ServiceWebImpl();
}
}
Register context for spring, but where need write Init.class for loading this config ?
public class Init implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(ConfigurationBean.class);
servletContext.addListener(new ContextLoaderListener(ctx));
ctx.setServletContext(servletContext);
}
}
Pls try this...
#Service
public class ServiceWebImpl implements ServiceWeb {
}
ServiceWeb bean is created inside ConfigurationBean class and its not visible at spring context level for autowiring.

(Spring MVC + Hibernate 4 + Test 4) autowired DAO return NULL

Maven Dependencies
<!-- SPRING MVC -->
<spring-version>4.0.3.RELEASE</spring-version>
<spring-test-version>4.2.1.RELEASE</spring-test-version>
<!-- TESTS -->
<junit-Version>4.11</junit-Version>
<!-- DATA BASE -->
<hibernate.version>4.1.5.Final</hibernate.version>
<hibernate-validator>4.2.0.Final</hibernate-validator>
<mysql.connector.version>5.1.32</mysql.connector.version>
AccountDao.java
#Repository
#Transactional
public class AccountDao {
private final SessionFactory sessionFactory;
#Inject
public AccountDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
[...]
}
Test
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {SpringMVCInitializer.class}, loader=AnnotationConfigContextLoader.class)
public class LoadingTests extends TestMachine {
#Autowired
private AccountDao accountDao;
AppConfig.java
#Configuration
#PropertySource("classpath:application.properties")
#ComponentScan(basePackages = "company")
#EnableTransactionManagement
public class AppConfig {
#Bean
public AccountDao accountDao() {
return new AccountDao();
}
#Bean
public PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
/*LOCAL*/
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/compamny");
dataSource.setUsername("root");
dataSource.setPassword("");
return dataSource;
}
#Bean(name = "sessionFactory")
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan("insynctive.model");
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(Environment.HBM2DDL_AUTO, "create");
properties.put(Environment.DIALECT, "org.hibernate.dialect.MySQLDialect");
properties.put(Environment.SHOW_SQL, true);
return properties;
}
}
SpringMVCConfiguration.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="company.controller")
public class SpringMVCConfiguration extends WebMvcConfigurerAdapter {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolverJSP = new InternalResourceViewResolver();
viewResolverJSP.setOrder(1);
viewResolverJSP.setViewClass(JstlView.class);
viewResolverJSP.setPrefix("views/jsp/");
viewResolverJSP.setSuffix(".jsp");
return viewResolverJSP;
}
}
SpringMVCInitializer.java
public class SpringMVCInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {AppConfig.class, SpringMVCConfiguration.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
My autowired of AccountDao is returning null Why? but in my web application everything works good.
I Try lot of things like:
Create a new sessionFactory but doesn't work.
Used: classes ={AppConfig.class,SpringMVCConfig.class}.
Used: #ContextConfiguration(initializers = {SpringMVCInitializer.class}, loader=AnnotationConfigContextLoader.class) throw Type mismatch: cannot convert from Class to Class>
Used: #SpringApplicationConfiguration(classes = {SpringMVCInitializer.class})
I think you need to set initializers instead of classes on your LoadingTests class.
#ContextConfiguration(initializers = {SpringMVCInitializer.class}, loader=AnnotationConfigContextLoader.class)
Also please consider using constructor injection on your DAO.
Since you have #Repository you should include them with
#EnableJpaRepositories(basePackages="yourrepositories") at your config class
try adding
#WebAppConfiguration
before you test class.
The mere presence of #WebAppConfiguration on a test class ensures that a
WebApplicationContext will be loaded for the test using a default for
the path to the root of the web application.
I resolved this making a HibernateUtils to create a sessionFactory.

Categories