I'm using Apache Tomcat 7.0.54 and Spring MVC 4.0.1 and trying to configure DispatcherServlet with Java:
I've written the config class:
public class AppInitializer extends AbstractDispatcherServletInitializer{
#Override
protected WebApplicationContext createServletApplicationContext() {
XmlWebApplicationContext context = new XmlWebApplicationContext();
context.setConfigLocation("/WEB-INF/her-servlet.xml");
return context;
}
#Override
protected String[] getServletMappings() {
return new String[] {"*.her"};
}
#Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
and it doesn't work. But if I write the follwoing:
public class AppInitializer implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext sc) throws ServletException {
XmlWebApplicationContext context = new XmlWebApplicationContext();
context.setConfigLocation("/WEB-INF/her-servlet.xml");
ServletRegistration.Dynamic registration = sc.addServlet("her", new DispatcherServlet(context));
registration.setLoadOnStartup(1);
registration.addMapping("*.her");
}
}
It'll work fine. I don't understand the problem. Could you help me to solve?
Related
Is it possible for TestContainer to receive data from ServletContext as in the following case?
public class LinkResourceTest extends JerseyTest {
#Override
protected Application configure() {
ResourceConfig config = new ResourceConfig(LinkResource.class);
config.register(StatusResponseFilter.class);
config.register(JacksonFeature.class);
config.register(MultiPartFeature.class);
config.register(ExceptionMapperFeature.class);
config.register(JacksonContextResolver.class);
config.register(DatabaseFeature.class);
return config;
}
#Override
protected void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
}
}
The config.register(DatabaseFeature.class); line makes trouble because DatabaseFeature needs a ServletContext in the constructor, which I have for production.
public class DatabaseFeature implements Feature {
private ServletContext servletContext;
public DatabaseFeature(#Context ServletContext servletContext) {
this.servletContext = servletContext;
}
#Override
public boolean configure(FeatureContext context) {
context.register(new DatabaseBinding(servletContext));
return true;
}
}
set active profile like context.getEnvironment().setActiveProfiles( "DEV" );
which can be achieved by using
public class SpringWebInitializer implements WebApplicationInitializer
{
public void onStartup( final ServletContext servletContext ) throws ServletException
{
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.getEnvironment().setActiveProfiles("DEV" )
}
}
But when extending AbstractAnnotationConfigDispatcherServletInitializer .
how can we achieve setting active profile ?
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
}
Activate your profile by using spring.profiles.active property.
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.setInitParameter("spring.profiles.active", "DEV");
}
}
You have a few options..
You can try having a context initializer to load the spring profile from a properties file on the classpath, like the following:
public class ContextProfileInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final Logger LOGGER = LoggerFactory.getLogger(ContextProfileInitializer.class);
private static final String DEFAULT_SPRING_PROFILE = "local";
#Override
public void initialize(final ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
try {
environment.getPropertySources().addFirst(new ResourcePropertySource("classpath:conf/application.properties"));
if (environment.getProperty("spring.profiles.active") == null) {
environment.setActiveProfiles(DEFAULT_SPRING_PROFILE);
}
LOGGER.info("Activated Spring Profile: " + environment.getProperty("spring.profiles.active"));
} catch (IOException e) {
LOGGER.error("Could not find properties file in classpath.");
}
}
}
Here are some guides with more info:
https://gist.github.com/rponte/3989915
http://www.java-allandsundry.com/2014/09/spring-webapplicationinitializer-and.html
Alternatively (and a much easier way!) Use Spring Boot.
You can simply define spring.profiles.active in an application.properties file in the classpath. This will automatically be picked up and loaded into your environment.
More info here:
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html
You can use #ActiveProfiles("DEV") on some of your #Configuration classes, but probably more useful would be passing profile from outside - just run your .jar with additional parameter like -Dspring.active.profiles=DEV
I think it should be rather: -Dspring.profiles.active=... (Spring 4.1.5)
After I update my web application from Spring 4.1.0 to 4.1.2, the resource mapping stop working.
Without any change, each request to any resource is returning "HTTP 404 - NOT FOUND"(.js, .png, etc...).
Then I switch back to Spring 4.1.0, and everything becomes to work again.
This is my application configuration class:
public class MvcConfiguration extends WebMvcConfigurationSupport {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/**");
}
}
This question is similar to this: Resource Not Found after Spring 4.1.2 Update when deploy with JRebel 6.0.0
My resources are at:
[project]\WebContent\resources
And this is my servlet initializer:
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer implements HttpSessionListener {
private static final int MAX_UPLOAD_SIZE = 1 * 1024 * 1024; // 1mb;
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { MvcConfiguration.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceEncoding(true);
return new Filter[] { encodingFilter, new MultipartFilter() };
}
#Override
protected void customizeRegistration(Dynamic registration) {
File uploadDirectory = new File(System.getProperty("java.io.tmpdir"));
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(uploadDirectory.getAbsolutePath(), MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
registration.setMultipartConfig(multipartConfigElement);
}
Just change your resource handler to the following:
public class MvcConfiguration extends WebMvcConfigurationSupport {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
This broke the code for me too when upgrading from Spring 4.1.1, but removing the trailing /** in Spring 4.1.6 fixed this.
I cannot seem to get simple Spring application to work with JavaConfig.
public class WebApp extends AbstractAnnotationConfigDispatcherServletInitializer {
private static final Logger logger = Logger.getLogger(WebApp.class);
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[0];
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{ WebAppConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[]{ "/" };
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
logger.debug("onStartup");
super.onStartup(servletContext);//MUST HAVE
servletContext.setInitParameter("defaultHtmlEscape", "true");
}
#Configuration
#EnableWebMvc
#ComponentScan("com.doge.controller")
public static class WebAppConfig extends WebMvcConfigurerAdapter {
}
}
And controller:
package com.doge.controller;
#RestController
public class HelloController {
#RequestMapping("/")
public String sayHello() {
System.out.println("something");
return "index";
}
}
I always get 404 on "localhost:8080/Build" nor "localhost:8080".
Nothing is ever logged nor printed, just "INFO: Server startup in 538 ms".
There are few options of initialize Spring web application. The easiest is like below:
public class SpringAnnotationWebInitializer extends AbstractContextLoaderInitializer {
#Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext applicationContext =
new AnnotationConfigWebApplicationContext();
applicationContext.register(WebAppConfig.class);
return applicationContext;
}
}
Other options can be found here: http://www.kubrynski.com/2014/01/understanding-spring-web-initialization.html
I want to create Bean using Spring annotations and without any XML configuration. I have something like public class WebAppInitializer implements WebApplicationInitializer which load all application context.
I have my bean as a class:
#ManagedResource(objectName = "myBean.example:name=MonitoringService")
#Component
public class MonitoringService implements IMonitoringService {
public static final Logger LOG = LoggerFactory.getLogger(MonitoringService.class);
private boolean isDbServicesEnabled = true;
#ManagedAttribute(description = "DBServices configurator")
public boolean isDbServicesEnabled() {
return isDbServicesEnabled;
}
#ManagedAttribute(description = "DBServices configurator")
public void setDbServicesEnabled(boolean dbServicesEnabled) {
LOG.info("DBServices " + (isDbServicesEnabled ? "enabled" : "disabled"));
isDbServicesEnabled = dbServicesEnabled;
}
}
and simple interface:
public interface IMonitoringService {
public boolean isDbServicesEnabled();
public void setDbServicesEnabled(boolean dbServicesEnabled);
}
I deploy it to Glassfish 3 server and everything work ok, but I can not see it JConsole.
Where is the problem?
I also use SimonMXBeanManager for statistics and it wrapper works ok.
Do I have to register it in MBeanServer?
This is a class for SimonManager configuration:
#Configuration
public class MonitoringConfiguration {
#Bean
public Manager simonManager() throws Exception {
ManagerFactoryBean managerFactoryBean = new ManagerFactoryBean();
Callback jmxRegisterCallback = new JmxRegisterCallback(mBeanServer(), "myBean.example");
managerFactoryBean.setCallbacks(Lists.newArrayList(jmxRegisterCallback));
return managerFactoryBean.getObject();
}
#Bean
public SimonManagerMXBeanWrapper simonManagerMXBean() throws Exception {
return new WebApplicationSimonManagerMXBeanWrapper(new SimonManagerMXBeanImpl(simonManager()));
}
#Bean
public MBeanServer mBeanServer() {
MBeanServerFactoryBean mBeanServerFactoryBean = new MBeanServerFactoryBean();
mBeanServerFactoryBean.setLocateExistingServerIfPossible(true);
mBeanServerFactoryBean.afterPropertiesSet();
return mBeanServerFactoryBean.getObject();
}
#Bean
public AnnotationMBeanExporter annotationMBeanExporter() {
return new AnnotationMBeanExporter();
}
#ManagedResource(objectName = "myBean.example:name=SimonManager")
private class WebApplicationSimonManagerMXBeanWrapper extends SimonManagerMXBeanWrapper {
public WebApplicationSimonManagerMXBeanWrapper(SimonManagerMXBean delegate) {
super(delegate);
}
}
and a class which loads application context:
public class WebAppInitializer implements WebApplicationInitializer {
String[] locations = new String[] {
"myBean.example"
};
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(
RootContextConfig.class
);
rootContext.scan(locations);
rootContext.refresh();
container.addListener(new RequestContextListener());
container.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(WebAppConfig.class);
ServletRegistration.Dynamic dispatcher = container.addServlet(
"dispatcher", new DispatcherServlet(dispatcherContext)
);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
createSimonWebConsole(container);
}
private void createSimonWebConsole(ServletContext container) {
ServletRegistration.Dynamic dn =
container.addServlet("simon-webconsole", new SimonConsoleServlet());
dn.setInitParameter("url-prefix", "/javasimon-console");
dn.addMapping("/javasimon-console/*");
}
}
Ok, I figured out, that I have to add #ComponentScan annotation with "myBean.example" namespace to class MonitoringConfiguration. Now I can configure my services in JConsole.