I write Configuration WSDL Servcie java class and have a method called requestDispatcher that get ApplicationContext and return ServletRegistrationBean.
I try to return ServletRegistrationBean by implementing with the constructor as shown :
public ServletRegistrationBean(T servlet,
String... urlMappings) .
To the T servlet parameter i pass messageDispatcherServlet and i get an error that
"Constractor ServletRegistrationBean (MessageDispatcherServlet,String)
is not defined".
I saw on google exmpales of code that do the same.
I would be glad for any help
This is the method i wrote:
public class WSDLConfigService {
#Bean
public ServletRegistrationBean requestDispatcher (ApplicationContext conext){
MessageDispatcherServlet msd = new MessageDispatcherServlet();
msd.setApplicationContext(conext);
msd.setTransformWsdlLocations(true);
return new ServletRegistrationBean(msd, "/soap/*");
}
Related
I am trying to develop a simple Spring MVC with no XML application .its basically show a simple home page. I am using tomcat on JetBrains IDE for development and problem is that when I run it on tomcat I see 404 error this is url http://localhost:8080/MySpringSecurityApp_war/
this is a controller
#Component
public class DemoController {
#GetMapping("/")
public String showHome(){
return "home";
}
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.luv2code.springsecurity.demo")
public class DemoAppConfig {
//define a bean for view resolver
#Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
public class MySpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {DemoAppConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
this is error log
9-Jun-2020 13:32:07.511 WARNING [http-nio-8080-exec-1] org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/MySpringSecurityApp_war/] in DispatcherServlet with name 'dispatcher'
09-Jun-2020 13:32:07.604 WARNING [http-nio-8080-exec-4] org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/MySpringSecurityApp_war/] in DispatcherServlet with name 'dispatcher'
this is also how my project structure
You need to define a resource path if you adding something into your URL (after host part basically in your case MySpringSecurityApp_war) you are calling localhost:8080/MySpringSecurityApp_war/ but you didn't define the resource path anywhere so I guess what you need to do is either add #RequestMapping("/MySpringSecurityApp_war/") at class level or just call localhost:8080/ without any resource path
You can also use #RestController in place of #Component.
I hope it will work.
I'm running a hello-world Spring WebMVC sample of 3 classes: WebApplicationInitializer, WebMvcConfigurer and simple controller with a single request handler method.
Inside WebApplicationInitializer 'onStartup(ctxt)' the DispatcherServlet instance is mapped to '/app/*' URL pattern and reflected in ctxt.context.context.servletMapping value as {*.jspx=jsp, /app/*=dispatcher, *.jsp=jsp, /=default} in runtime.
But for unknown reason GET e.g. 'http://localhost:8080/app/sht' is dispatched to Tomcat's DefaultServlet! In runtime the request's context servlet mapping(request.request.applicationMapping.mappingData.context.servletMapping) value states that onStartup() configuration is lost: {*.jspx=jsp, *.jsp=jsp, /=default}
Could you please assist in configuring Spring properly? Thanks!
Spring 5.2.2; Tomcat 9.0.30, running under Eclipse.
public class WebbAppInitializer implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext context) throws ServletException{
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.setServletContext(context);
dispatcherContext.register(SpringWebConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = context.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/app/*");
}
}
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = { "cool.videoservice.controller" })
public class SpringWebConfig implements WebMvcConfigurer{
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/view/");
bean.setSuffix(".jsp");
return bean;
}
}
#Controller
public class IndexController{
#GetMapping("/sht")
public String greeting(#RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
System.out.println("Oh, yeah!!!!!!");
return "index";
}
}
I have a Servlet Filter within my Spring Boot (2.0.1) application that I'm registering with FilterRegistrationBean which I need it to be executed first (order of one) along the filter chain. The application is deployed to JBoss 7.2. This filter also has a dependency that is injected with #Autowired (see below):
package my.pkg.com
#SpringBootApplication
#ComponentScan(basePackages={"my.pkg.com"})
public class MyApp extends SpringBootServletInitializer {
public satic void main(String[] args) throws IOException {
SpringApplication.run(MyApp.class, args);
}
#Bean
#Order(1)
public FilterRegistrationBean<MyFilter> myFilter() {
FilterRegistrationBean<MyFilter> contextFilter = new FilterRegistrationBean<>();
contextFilter.setFilter(new MyFilter());
contextFilter.addUrlPattern("/api/*");
return contextFilter;
}
}
package my.pkg.com.filter
public class MyFilter extends Filter {
#Autowired
private MyService mySrv;
#Override
public void doFilter(…) {
mySrv.doSomething(); // mySrv is null
}
}
The problem is when the application is deployed and ran, when the Servlet request gets to MyFilter.doFilter(), mySrv is null which means MyFilter was never scanned for dependency injections.
I can verify through debugging MyService which is a #Repository in my.package.com.repository package does get initialized. It just never gets injected into MyFilter.
I can create a constructor for MyFilter to take MyService, then #Autowired MyService into MyApp and during filter registration, I can pass it to this constructor, which resolves the issue.
However, I want to know if there is anything I'm doing wrong that this dependency doesn't get injected into MyFilter with using the setup above alone.
If you create an object by yourself, using new, and this object is not returned by a #Bean-annotated method, then it's not a Spring bean, and Spring will thus not inject anything in it.
You can just add an #Bean-annotated method returning new MyFilter(), and call that method from myFilter() to get the bean, or add a MyFilter as argument to myFilter().
Example:
#Bean
#Order(1)
public FilterRegistrationBean<MyFilter> myFilter() {
FilterRegistrationBean<MyFilter> contextFilter = new FilterRegistrationBean<>();
contextFilter.setFilter(theActualFilter());
contextFilter.addUrlPattern("/api/*");
return contextFilter;
}
#Bean
public MyFilter theActualFilter() {
return new MyFilter(); // now this is a Spring bean
}
or
#Bean
#Order(1)
public FilterRegistrationBean<MyFilter> myFilter(MyFilter theActualFilter) {
FilterRegistrationBean<MyFilter> contextFilter = new FilterRegistrationBean<>();
contextFilter.setFilter(theActualFilter);
contextFilter.addUrlPattern("/api/*");
return contextFilter;
}
#Bean
public MyFilter theActualFilter() {
return new MyFilter(); // now this is a Spring bean
}
It's simple, add #Component annotation on your filter class and it will make #Autowired annotation working inside as Spring dependency injection will process your filter class and inject the service bean.
I created a spring boot application with a parent context (services) and child context (spring-webmvc controllers):
#Configuration
public class MainApiApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.parent(Services.class)
.child(ApiOne.class, MainApiApplication.class)
.run(args);
}
#Bean
public EmbeddedServletContainerFactory servletContainer() {
return new TomcatEmbeddedServletContainerFactory();
}
}
Now I want to add another client context (and DispatcherServlet) for my ApiTwo.class configuration. I think I have to do two things:
Move the servletContainer (thus the MainApiApplication.class configuration) out of the child context and
add a path mapping /one/ -> ApiOne.class and /two/ ApiTwo.class
What is the spring boot way to do it?
As #josh-ghiloni already said, you need to register a ServletRegistrationBean for every isolated web context you want to create.
You need to create an application context from a xml or java config class. You can use #Import and #ComponentScan annotation to add shared services to the parent context. Here is an example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
//#ComponentScan({"..."})
//#Import({})
public class Starter {
public static void main(String[] args) throws Exception {
SpringApplication.run(Starter.class, args);
}
#Bean
public ServletRegistrationBean apiV1() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
applicationContext.setConfigLocation("classpath:/META-INF/spring/webmvc-context.xml");
dispatcherServlet.setApplicationContext(applicationContext);
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/1/*");
servletRegistrationBean.setName("api-v1");
return servletRegistrationBean;
}
#Bean
public ServletRegistrationBean apiV2() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(ResourceConfig.class);
dispatcherServlet.setApplicationContext(applicationContext);
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/2/*");
servletRegistrationBean.setName("api-v2");
return servletRegistrationBean;
}
}
Create a ServletRegistrationBean that declares the servlet and its mappings. You will probably also want to exclude DispatcherServletAutoConfiguration from the autoconfigurations called, because it will register a DispatcherServlet at / and override yours
EDIT Despite my comment below saying you might not need this, unless you need your APIs running on separate ports (and it doesn't sound like you do), Dave Syer, one of the authors of Spring Boot, answered a very similar question here: Configure multiple servletcontainers/servlets with spring boot
I have a config file like
package com.mypackage.referencedata.config;
#Configuration
#ComponentScan ("com.mypackage.referencedata.*")
public class ReferenceDataConfig {
In a spring xml if I have
<context:component-scan base-package="com.mypackage.referencedata.config.*" />
it does not get loaded.
If I use
<context:component-scan base-package="com.mypackage.referencedata.*" />
it works.
What gives? I'd expect the 1st to work as well.
<context:component-scan base-package="com.mypackage.referencedata.config.*" />
Will scan packages inside com.mypackage.referencedata.config as it is package.
com.mypackage.referencedata.config
Will work fine.
You don't need to scan the #Configuration class in component scan in SpringFramework. But you need to register it in the Application Initializer class of your web application that defines the configuration required as in web.xml file. You need to implement WebApplicationInitializer interface there and define onStartup method.
In that onStartup method you need to register your #Configuration class to the rootContext of your web application. Please take a look at the following code snippet.
1. The class that works as web.xml
public class ApplicationInitializer implements WebApplicationInitializer {
//Called first when the application starts loading.
public void onStartup(ServletContext servletContext)
throws ServletException {
System.out.println("Inside application initializer...");
//Registering the class that incorporates the annotated DispatcherServlet configuration of spring
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(DispatcherConfig.class);
//Adding the listener for the rootContext
servletContext.addListener(new ContextLoaderListener(rootContext));
//Registering the dispatcher servlet mappings.
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
2. The #Configuration class of web application holds the beans and other setups.
#EnableWebMvc
#Configuration
#ComponentScan(basePackages={"com.abcprocure.servicerepo.controller", "com.abcprocure.servicerepo.model", "com.abcprocure.servicerepo.service"})
public class DispatcherConfig extends WebMvcConfigurerAdapter {
//Registers the url paths for resources to skip from spring. Eg. JS, CSS and images.
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// TODO Auto-generated method stub
registry.addResourceHandler("/js/**").addResourceLocations("/js/**");
registry.addResourceHandler("/html/**").addResourceLocations("/html/**");
}
//Defines the ViewResolver that Spring will use to render the views.
#Bean
public ViewResolver viewResolver() {
System.out.println("Inside View Resolver...");
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
//Defines the DataSource to use in the application.
#Bean
public DataSource dataSource() {
System.out.println("Inside DataSource bean creation....");
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
dataSource.setUrl("jdbc:sqlserver://192.168.100.131;databaseName=test");
dataSource.setUsername("egptender");
dataSource.setPassword("egp#123");
return dataSource;
}
//Defines the Hibernate's SessionFactory.
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource()).addAnnotatedClasses(Services.class, Operations.class, OperationParameters.class, ServiceModels.class, Businesslogic.class,TblFormMaster.class,TblFormBuilder.class);
builder.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
builder.setProperty("hibernate.show_sql", "true");
return builder.buildSessionFactory();
}
}
Hope this helps you. Cheers.
If you are using maven, check if you have correct dependencies