InternalResourceViewResolver cannot find page - java

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

Spring configuration without Spring Boot

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";
}
}

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{
}

Test if model contains some attribute and its value

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.

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.

Categories