No mapping found for HTTP request with URI error? - java

I wrote a spring boot project.
It has three files.
Appconfig.java
package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#EnableWebMvc
#ComponentScan
(basePackages = {"controller"})
public class AppConfig {
}
ServletInitilizer.java
package config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[0];
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{AppConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
HelloController.java
package controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
public class HelloController {
#RequestMapping("hi")
#ResponseBody
public String hi() {
return "Hello, world.";
}
}
When I try to run it, it has error "No mapping found for HTTP request with URI [/SpringC1_01/] in DispatcherServlet with name 'dispatcher'".
Is this because server didn't find the controller or other reason? Thx.

Yes. i suspect two issues in the code.
#SpringBootApplication annotation is missing in AppConfig.
#RestController annotation is missing in HelloController.

Most of all you are missing a couple of things here.
Main class which contains public static void main and this class should be annotated with #SpringBootApplication
HelloController should be annotated with #RestController
At method level it should definitely point to some HTTP method in your case perhaprs it is Get mapping, so add #GetMapping annotation arround the method.
Move RequestMapping annotation from method level and add it to HelloController class.

Related

Spring MVC can't find mappings

I am trying to get my OrderController to work, but MVC can't seem to find it. Does anyone know why this happens?
Initializer class. The getServletMapping method keeps notifying me about Not annotated method overrides method annotated with #NonNullApi
package configs;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{Config.class};
}
#Override
protected String[] getServletMappings() {
return new String[] { "/api/*" };
}
}
The config class.
package configs;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.sql.DataSource;
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = {"model"})
#PropertySource("classpath:/application.properties")
public class Config {
#Bean
public JdbcTemplate getTemplate(DataSource ds) {
return new JdbcTemplate(ds);
}
#Bean
public DataSource dataSource(Environment env) {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.hsqldb.jdbcDriver");
ds.setUrl(env.getProperty("hsql.url"));
var populator = new ResourceDatabasePopulator(
new ClassPathResource("schema.sql"),
new ClassPathResource("data.sql")
);
DatabasePopulatorUtils.execute(populator, ds);
return ds;
}
}
Then the controller.
package controllers;
import model.Order;
import model.OrderDAO;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
public class OrderController {
private OrderDAO orderdao;
public OrderController(OrderDAO orderDAO) {
this.orderdao = orderDAO;
}
#PostMapping("orders")
#ResponseStatus(HttpStatus.CREATED)
public Order saveOrder(#RequestBody Order order) {
return orderdao.addOrder(order);
}
#GetMapping("orders/{id}")
public Order getOrderById(#PathVariable Long id) {
return orderdao.getOrderById(id);
}
#GetMapping("orders")
public List<Order> getOrders() {
return orderdao.getAllOrders();
}
#DeleteMapping("orders/{id}")
public void deleteOrderById(#PathVariable Long id) {
orderdao.deleteOrderById(id);
}
}
Everything seems fine, I can't find the issue.
Since the OrderController is in the controllers package, I forgot to add the package in the configs componentScan parameters.
Your controller registers the endpoints at /orders/*, but in getServletMappings you specify the /api/*. You should add /api prefix to your controller, like this
#RestController
#RequestMapping("api")
public class OrderController {
...

Can't import `configureRepositoryRestConfiguration` in Spring

I have extended my class from RepositoryRestMvcConfiguration according to documentation it has configureRepositoryRestConfiguration method which can be implemented but when I try to override this method I can't import it :|
Can anybody tell me Why this problem occurred?
EDIT : according to current version configureRepositoryRestConfiguration method is not avialble.. so what method should I used instead of this?
Here is my code
MSARepositoryRestMvcConfiguration.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
#Configuration
public class MSARepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(MSARepositoryRestMvcConfiguration.class);
#Value("${static.path}")
private String staticPath;
// #Bean
// public PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder();
// }
#Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setBasePath("/api");
// config.exposeIdsFor(User.class,Order.class,HeroRating.class,RiderLocation.class,OrderItem.class,Address.class,ShopDetail.class,PromoCode.class,RiderDuty.class,Criteria.class,Setting.class);
config.setReturnBodyForPutAndPost(true);
config.setReturnBodyOnCreate(true);
config.setReturnBodyOnUpdate(true);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if(staticPath != null) {
LOG.info("Serving static content from " + staticPath);
registry.addResourceHandler("/photos/**").addResourceLocations("file:" + staticPath+"photos/");
registry.addResourceHandler("/").addResourceLocations("classpath:/static/");
}
}
#Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
}
Error
It gives an error on configureRepositoryRestConfiguration to remove override annotation
ErrorMessage
The method configureRepositoryRestConfiguration(RepositoryRestConfiguration) of type MSARepositoryRestMvcConfiguration must override or implement a supertype method
From the current reference documentation, Configuring Spring Data REST:
To customize the configuration, register a RepositoryRestConfigurer (or extend RepositoryRestConfigurerAdapter) and implement or override the configureā€¦-methods relevant to your use case.
SDR configuration outside of RepositoryRestMvcConfiguration was addressed in DATAREST-621 and RepositoryRestConfigurer was introduced in this commit.
According to current version of spring document this method is not available so instead of `configureRepositoryRestConfiguration' we can override following method
#Configuration
public class MSARepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {
#Override
public RepositoryRestConfiguration config() {
RepositoryRestConfiguration config = super.config();
config.setBasePath("/api");
config.exposeIdsFor(User.class);
return config;
}
}
Check the current configureRepositoryRestConfiguration definition at Interface RepositoryRestConfigurer.
Example form https://www.baeldung.com/spring-data-rest-serialize-entity-id:
#Configuration
public class RestConfiguration implements RepositoryRestConfigurer {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
config.exposeIdsFor(Person.class);
}
}

Spring aop aspects not executing on annotations

I'm developing a WebSocket server application using spring.
Class PlayerHandler
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
/**
* Created by kris on 11.07.16.
*/
public class PlayerHandler extends TextWebSocketHandler{
public PlayerHandler(){}
#Override
#AuthorizationRequired
public void handleTextMessage(WebSocketSession session, TextMessage tm) throws IOException {
session.sendMessage(tm);
}
}
I want user to be authorized with every incoming request by token, so I created a Aspect UserAuthorization
package com.berrigan.axevor.authorization;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
#Aspect
#Component
public class UserAuthorization {
#Around("#annotation(com.berrigan.axevor.authorization.AuthorizationRequired)")
public void authorize(ProceedingJoinPoint jp) throws Throwable{
System.out.println("\n\n\n\n\Works\n\n\n\n\n\n");
jp.proceed();
}
}
I added the #AuthorizationRequired annotation, which indicates methods in which users are going to be authorized. Unfortunately method authorize never get called. I've added following code to my main class to check if the bean get created.
UserAuthorization ua = ctx.getBean(UserAuthorization.class); // ApplicationContext
if(au == null) System.out.println("is null")
But I don't get such log.
My spring config
#EnableAutoConfiguration
#Configuration
#EnableAspectJAutoProxy
#Import({com.berrigan.axevor.websocket.WebSocketConfig.class})
#ComponentScan(basePackages = {"com.berrigan.axevor"})
public class Config {}
Annotation code:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface AuthorizationRequired{}
#Configuration
#EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer{
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
registry.addHandler(playerHandler(), "/game").setAllowedOrigins("*");
}
#Bean
public WebSocketHandler playerHandler(){
return new PlayerHandler();
}
}
Solution found, corrupted pom.xml file. After regenerating it, everything works like a charm

Unable to load html pages when using Spring annotation config

I'm working on a POC using Spring with Annotation based configuration. While working on it, I'm facing below issues:
When I am using dispatcher servlet mapping as /, I am able to access the controllers but not html page.
When I change the mapping to /**, then I am able to access the html page but not the controllers.
I am not sure if I should add another dispatcher servlet and add one mapping in it. I also tried passing both the mappings in the dispatcher servlet, but it didn't work.
Maybe someone can help me with the issue.
Below is the code:
AppConfig
package com.upload.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
#Configuration
#Import(WebConfig.class)
#ComponentScan(basePackages= "com.upload")
public class AppConfig {
}
WebConfig
package com.upload.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter{
}
ServletInitializer
public class ServletInitializer extends AbstractDispatcherServletInitializer {
#Override
protected WebApplicationContext createServletApplicationContext() {
final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
context.getEnvironment().setActiveProfiles("prod");
return context;
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
#Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
FileUploadController
#Controller
#RequestMapping("/ws")
public class FileUploadController {
#RequestMapping(value="hello",method=RequestMethod.GET)
public String hello(){
return "Hello";
}
}
Use Following Approach:
You need to add addResourceHandler to pick up the html page from the web-inf structure WEB-INF/views/viewer where all your pages like: js/ html /css/ images etc are present. You can remove your AppConfig .java shown above.
package com.Configuration.si.config;
#Configuration
#ComponentScan("com.Configuration.si")
#EnableWebMvc
public class Configuration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/viewer/**","/lib/**","/js/**","/images/**","/css/**","/swf/**")
.addResourceLocations("/WEB-INF/views/viewer/","/WEB-INF/views/lib/","/WEB-INF/views/js/","/WEB-INF/views/images/","/WEB-INF/views/css/","/WEB-INF/views/swf/")
.setCachePeriod(315569126);
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
Also Add this class to your structure
package com.Configuration.si.config;
#Configuration
public class WebMvcConfiguration {
#Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/WEB-INF/views/");
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
}
Internal view resolver will resolve the page you need using model.setViewName("login"); in controller. Hope it will help you

AbstractSecurityWebApplicationInitializer vs. AbstractAnnotationConfigDispatcherServletInitializer

I'm trying to add security to my Spring 3.2.8-based pure Java-configured application. I'm following the instructions http://docs.spring.io/spring-security/site/docs/3.2.2.RELEASE/reference/htmlsingle/#jc
I've completed section 3.1, and the documentation says at this point that every URL should require authentication, but none do (at least, I can load every URL). It says it creates a Servlet filter, etc.
It's evident that by itself, that WebSecurityConfigurerAdapter subclass is not enough. So I look at section 3.1.1, which says the next step is to register the springSecurityFilterChain with the WAR, and goes on to say how in a Servlet 3+ environment, I need to subclass AbstractSecurityWebApplicationInitializer. But I'm already subclassing AbstractAnnotationConfigDispatcherServletInitializer. Am I supposed to have one of each? There is some discussion of ordering in the AbstractSecurityWebApplicationInitializer JavaDoc, implying I should have more than one initializer class.
In all this, it also said to add the WebSecurityConfigurerAdapter subclass to getRootConfigClasses() (although the example doesn't show the "AppConfig" that the other Spring getting started docs have you create; also, this alone wasn't enough).
So I tried adding another initializer class. All my other classes are public static inner classes of my AbstractAnnotationConfigDispatcherServletInitializer subclass, so I put another in there to be the AbstractSecurityWebApplicationInitializer subclass (rather than creating a separate .java file).
WARNING com.caucho.server.webapp.WebApp setConfigException: java.lang.UnsupportedOperationException: unimplemented
at com.caucho.server.webapp.ServletContextImpl.setSessionTrackingModes(ServletContextImpl.java:552)
at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.onStartup(AbstractSecurityWebApplicationInitializer.java:120)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174)
at com.caucho.server.webapp.WebApp.callInitializer(WebApp.java:3471)
at com.caucho.server.webapp.WebApp.callInitializers(WebApp.java:3439)
at com.caucho.server.webapp.WebApp.startImpl(WebApp.java:3661)
at com.caucho.server.webapp.WebApp$StartupTask.run(WebApp.java:5196)
at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
I tried adding ordering to no avail. My entire config:
package com.latencyzero.satdb.web;
//
// Java Imports
//
import java.util.Properties;
import java.util.ResourceBundle;
import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import javax.sql.DataSource;
//
// Library Imports
//
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
//
// Project Imports
//
/**
There are still some things that get configured in the container. This app
was developed using Resin. Things configured in resin's XML config for this
app include the data source, error page, key store password for Apple
Push Notifications (which should move to the DB).
*/
public
class
WebappInitializer
extends
org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
{
#Override
protected
Class<?>[]
getRootConfigClasses()
{
Class<?>[] classes = { AppConfig.class, SecurityConfig.class };
return classes;
}
#Override
protected
Class<?>[]
getServletConfigClasses()
{
Class<?>[] classes = { WebConfig.class };
return classes;
}
#Override
protected
java.lang.String[]
getServletMappings()
{
String[] mappings = { "/" };
return mappings;
}
#Override
protected
javax.servlet.Filter[]
getServletFilters()
{
return new javax.servlet.Filter[]
{
new org.springframework.orm.hibernate3.support.OpenSessionInViewFilter(),
};
}
/** *******************************************************************************************************************
App context configuration.
Hibernate config (data access, transactions, data model).
*/
#Configuration
#EnableAsync
#EnableTransactionManagement
#ComponentScan(basePackages = { "com.mymodelanddao", })
public
static
class
AppConfig
{
#Bean
public
org.springframework.jndi.JndiObjectFactoryBean
dataSource()
{
org.springframework.jndi.JndiObjectFactoryBean bean = new org.springframework.jndi.JndiObjectFactoryBean();
bean.setJndiName("java:comp/env/jdbc/db");
return bean;
}
#Bean
public
org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
sessionFactory()
{
DataSource dataSource = (DataSource) dataSource().getObject();
org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean bean = new org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean();
bean.setDataSource(dataSource);
// TODO: Do we need to scan this, since it's done as part of #ComponentScan?
bean.setPackagesToScan(new String[] {"com.latencyzero.satdb.model"});
Properties props = new Properties();
props.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
props.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
props.setProperty("hibernate.jdbc.batch_size", "200");
props.setProperty("hibernate.show_sql", "false");
props.setProperty("hibernate.format_sql", "true");
props.setProperty("hibernate.use_sql_comments", "false");
props.setProperty("hibernate.generate_statistics", "true");
bean.setHibernateProperties(props);
return bean;
}
#Bean
public
PlatformTransactionManager
transactionManager()
{
SessionFactory sf = sessionFactory().getObject();
org.springframework.orm.hibernate3.HibernateTransactionManager bean = new org.springframework.orm.hibernate3.HibernateTransactionManager();
bean.setSessionFactory(sf);
return bean;
}
private static Logger sLogger = Logger.getLogger(AppConfig.class);
}
/** *******************************************************************************************************************
Web context configuration.
*/
#Configuration
#EnableWebMvc
#ComponentScan(basePackageClasses = { com.mycontrollerclasses })
public
static
class
WebConfig
extends
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
{
#Bean
public
InternalResourceViewResolver
getInternalResourceViewResolver()
{
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public
org.springframework.web.multipart.commons.CommonsMultipartResolver
multipartResolver()
{
return new org.springframework.web.multipart.commons.CommonsMultipartResolver();
}
#Override
public
void
addResourceHandlers(ResourceHandlerRegistry inRegistry)
{
inRegistry.addResourceHandler("/assets/**").addResourceLocations("/assets/").setCachePeriod(31556926);
inRegistry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926);
inRegistry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
}
private static Logger sLogger = Logger.getLogger(WebConfig.class);
}
/** *******************************************************************************************************************
Security configuration.
*/
#Configuration
#EnableWebMvcSecurity
public
static
class
SecurityConfig
extends
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
{
#Autowired
public
void
configureGlobal(AuthenticationManagerBuilder inAuth)
throws
Exception
{
sLogger.warn("configureGlobal =================================================");
inAuth
.inMemoryAuthentication()
.withUser("user")
.password("password")
.roles("USER");
}
private static Logger sLogger = Logger.getLogger(SecurityConfig.class);
}
public
static
class
SecurityWebApplicationInitializer
extends
org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer
{
}
}
According to https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#abstractsecuritywebapplicationinitializer-with-spring-mvc, you have to introduce a second WebApplicationInitializer, typically derivating from AbstractSecurityWebApplicationInitializer
This second WebApplicationInitializer would register property the springFilterChain
Answering using 5.0.6 Spring Security version:
#EnableWebSecurity already contains #Configuration, therefore
specifying both is redundant
You are indeed required to have a second appinitializer, which extends AbstractSecurityWebApplicationInitializer. Your one seems OK
Your getRootConfigClasses is also OK.
You really should register SecurityConfig.class there.
Your thoughts and configuration seems right, except I'm not really sure if keeping your SecurityWebApplicationInitializer as static inner class allows Spring to find it. Maybe it can be a problem. I did all the configuration acc to above mentioned instruction and everything is working like a charm, redirecting me to "/login" page.

Categories

Resources