I have next project structure:
WebMvcConfiguration class:
#Configuration
#EnableWebMvc
#ComponentScan("com.test.controller")
public class WebMvcConfiguration {
#Bean
public InternalResourceViewResolver resolver() {
return new InternalResourceViewResolver("/WEB-INF/view/", ".html");
}
}
WebAppInitializer class:
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();
webApplicationContext.scan("com.test.configuration");
webApplicationContext.setServletContext(servletContext);
ServletRegistration.Dynamic servletDispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(webApplicationContext));
servletDispatcher.setLoadOnStartup(1);
servletDispatcher.addMapping("/");
}
}
CustomRestController class:
#RestController
public class CustomRestController {
#GetMapping(value = "/rest", produces = MediaType.TEXT_PLAIN_VALUE)
public String main() {
return "main";
}
}
CustomPageController class:
#Controller
public class CustomPageController {
#GetMapping("/page")
public String main() {
return "main";
}
}
Rest controller work as it should. But PageController fails with this Exception:
org.springframework.web.servlet.DispatcherServlet.noHandlerFound No mapping for GET /WEB-INF/view/main.html
I forgot to enable DefaultServletHandlerConfigurer in WebMvcConfiguration:
#Configuration
#EnableWebMvc
#ComponentScan("com.test.controller")
public class WebMvcConfiguration implements WebMvcConfigurer {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public InternalResourceViewResolver resolver() {
return new InternalResourceViewResolver("/WEB-INF/view/", ".html");
}
}
Related
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";
}
}
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);
}
}
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 am trying to implement a simple test for Java Spring Framework. Below is my code.
My Controller:
#RequestMapping(value = "/someMapping", method = RequestMethod.GET)
public String toTestMethod(Model model)
{
model.addAttribute("test", 1);
return "test";
}
Controller Test:
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup()
{
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#Test
public void testMethodTest() throws Exception
{
this.mockMvc.perform(get("/someMapping"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(model().attribute("test", 1));
}
Application context:
#Configuration
#EnableWebMvc
public class WebAppContext extends WebMvcConfigurerAdapter
{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
{
configurer.enable();
}
#Bean
public ViewResolver viewResolver()
{
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
When I run this test, it fails with the following exception
java.lang.AssertionError: Model attribute 'test' expected:<1> but was:<null>.
I have no idea why this happens, can someone please clarify?
If needed, I will provide any additional information.
So, in my case the problem was in the setup(), now it looks like this:
#Before
public void setup()
{
// this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
MyController ctrl = new MyController();
this.mockMvc = MockMvcBuilders.standaloneSetup(ctrl).build();
}
It started working as expected after this change.
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.