Does a Spring Boot Project that runs as a Jar needs a web.xml file? - spring-boot

As the title states.
I am migrating a Spring-MVC application that uses XML based Configuration.
I don't know where to move the filters located in the web.xml file to the new Spring Boot Project.

You can make use of the annotation : #ImportResource for this
Find more details here

You can define your filters using Java Configurations when using Spring Boot.
As mentioned in the documentation, you only need to declare that filter as a Bean in a configuration class.
#Configuration
public class WebConfig {
#Bean
public Filter someFilter() {
return new someFilter();
}
}
If for some reason "SomeFilter" is not a spring managed bean, or if you need to customize the filter behaviour, then you can register the filter using FilterRegistrationBean as follows
#Configuration
public class WebConfig {
#Bean
public Filter someFilter() {
return new someFilter();
}
#Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(someFilter());
return registration;
}
}
In case of multiple Filters you can specify the order using FilterRegistrationBean.setOrder() as mentioned in the doc

Finally I registered my Interceptors using Java Configuration (no xml) this way.
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Autowired
ControllerInterceptor controllerInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(this.controllerInterceptor).addPathPatterns(this.buildPaths());
}
private String[] buildPaths() {
String paths[] = { "/api/example1/**", "/api/example2/**" };
return paths;
}
}

Related

Problems adding spring webflow to a spring boot and joinfaces application

I am trying to add webflow to a spring boot app using joinfaces library.
I am using primefaces-spring-boot-starter and jetty-spring-boot-starter to configure jetty server.
Added necessary webflow dependencies to pom and configured necessary flowregistry, flowbuilderservices, flowexecutor and flowhandlermapping, ...
The application start correctly, reads the flows definitions from xmls and if enter to a flow via url the decision states are running correctly, reads the corresponding view state .xhtml file, calls the managed bean methods, and all are working apparently well.
But... once finished executing bean methods, when I hope to html be rendered in browser, the application is redirected to app root folder without any error in the log.
I have this behavior with all the flows of the application. Bean methods are executed correctly and when I hope to see the html... redirected to root.
Anyone tried to add webflow to a joinfaces jsf application successfully? I am missing to override some default configuration of joinfaces?
Thanks.
public class MvcConfiguration implements WebMvcConfigurer {
#Autowired
private WebFlowConfiguration webFlowConfiguration;
#Bean
public FlowHandlerMapping flowHandlerMapping() {
FlowHandlerMapping handlerMapping = new FlowHandlerMapping();
handlerMapping.setOrder(-1);
handlerMapping.setFlowRegistry(this.webFlowConfiguration.flowRegistry());
return handlerMapping;
}
#Bean
public FlowHandlerAdapter flowHandlerAdapter() {
JsfFlowHandlerAdapter adapter = new JsfFlowHandlerAdapter();
adapter.setFlowExecutor(this.webFlowConfiguration.flowExecutor());
return adapter;
}
#Bean
public ViewResolver faceletsViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setViewClass(JsfView.class);
resolver.setPrefix("/");
resolver.setSuffix(".xhtml");
return resolver;
}
}
#Configuration
public class WebFlowConfiguration extends AbstractFacesFlowConfiguration {
#Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder()
.setBasePath("classpath*:/META-INF/resources/flows")
.addFlowLocationPattern("/**/*.xml")
.setFlowBuilderServices(flowBuilderServices())
.build();
}
#Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder()
.setDevelopmentMode(true)
.setViewFactoryCreator(new JsfViewFactoryCreator())
.build();
}
#Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry())
.addFlowExecutionListener(new FlowFacesContextLifecycleListener())
.addFlowExecutionListener(new SecurityFlowExecutionListener())
.setMaxFlowExecutionSnapshots(0)
.build();
}
}

Add a Servlet Filter in a Spring Boot application

I'd like to have ETag suport. For this purpose there is a ShallowEtagHeaderFilter which does all the work. How can I add it without declaring it in my web.xml (which actually does not exist, because I somehow got by without it so far)?
P.S. I use Spring Boot 1.1.4
P.P.S. Here's a full solution
package cuenation.api;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import javax.servlet.DispatcherType;
import java.util.EnumSet;
#Configuration
public class WebConfig {
#Bean
public FilterRegistrationBean shallowEtagHeaderFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ShallowEtagHeaderFilter());
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
registration.addUrlPatterns("/cue-categories");
return registration;
}
}
When using Spring Boot
As mentioned in the reference documentation, the only step needed is to declare that filter as a Bean in a configuration class, that's it!
#Configuration
public class WebConfig {
#Bean
public Filter shallowEtagHeaderFilter() {
return new ShallowEtagHeaderFilter();
}
}
When using Spring MVC
You're probably already extending a WebApplicationInitializer. If not, then you should convert your webapp configuration from a web.xml file to a WebApplicationInitializer class.
If your context configuration lives in XML file(s), you can create a class that extends AbstractDispatcherServletInitializer - if using configuration classes, AbstractAnnotationConfigDispatcherServletInitializer is the proper choice.
In any case, you can then add Filter registration:
#Override
protected Filter[] getServletFilters() {
return new Filter[] {
new ShallowEtagHeaderFilter();
};
}
Full examples of code-based Servlet container initialization are available in the Spring reference documentation.
A bit late answer.
My solution was to create custom annotation:
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
// ...
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
#Component
public #interface Filter {
#AliasFor(annotation = Component.class, attribute = "value")
String value() default "";
}
And then simply apply it to the filter implementations:
#Filter
public class CustomFilter extends AbstractRequestLoggingFilter {
#Override
protected void beforeRequest(HttpServletRequest request, String message) {
logger.debug("before req params:", request.getParameterMap());
}
#Override
protected void afterRequest(HttpServletRequest request, String message) {
logger.debug("after req params:", request.getParameterMap());
}
}
See more: #AliasFor, Spring custom annotations question

Togglz with Spring #Configuration bean

I'm trying to implement Togglz & Spring using #Configuration beans rather than XML. I'm not sure how to configure the return type of the Configuration bean. For example:
#Configuration
public class SystemClockConfig {
#Bean
public SystemClock plainSystemClock() {
return new PlainSystemClock();
}
#Bean
public SystemClock awesomeSystemClock() {
return new AwesomeSystemClock();
}
#Bean
public FeatureProxyFactoryBean systemClock() {
FeatureProxyFactoryBean proxyFactoryBean = new FeatureProxyFactoryBean();
proxyFactoryBean.setActive(awesomeSystemClock());
proxyFactoryBean.setInactive(plainSystemClock());
proxyFactoryBean.setFeature(Features.AWESOME_SYSTEM_CLOCK.name());
proxyFactoryBean.setProxyType(SystemClock.class);
return proxyFactoryBean;
}
}
The systemClock method returns a FeatureProxyFactoryBean but the clients of this bean require a SystemClock. Of course, the compiler freaks over this.
I imagine it just works when XML config is used. How should I approach it when using a configuration bean?
I'm not an expert for the Java Config configuration style of Spring, but I guess your systemClock() method should return a proxy created with the FeatureProxyFactoryBean. Something like this:
#Bean
public SystemClock systemClock() {
FeatureProxyFactoryBean proxyFactoryBean = new FeatureProxyFactoryBean();
proxyFactoryBean.setActive(awesomeSystemClock());
proxyFactoryBean.setInactive(plainSystemClock());
proxyFactoryBean.setFeature(Features.AWESOME_SYSTEM_CLOCK.name());
proxyFactoryBean.setProxyType(SystemClock.class);
return (SystemClock) proxyFactoryBean.getObject();
}
But I'm not sure if this is the common way to use FactoryBeans with Spring Java Config.

Spring #Configuration bean created in #Bean method not enhanced by CGLIB

I'm trying to create a MainConfig that imports another Config by using an #Bean method instead of #Import like this :
#Configuration
public class MainConfig {
#Bean
public Service service() {
return new Service(infrastructureConfig().database());
}
#Bean
public OtherService otherService() {
return new OtherService(infrastructureConfig().database());
}
#Bean
public InfrastructureConfig intrastructureConfig() {
return new InfrastructureConfig();
}
}
#Configuration
public class InfrastructureConfig {
#Bean
public Database database() {
return new Database();
}
...
}
When using this technique, the Database is created twice because Spring doesn't seem to consider the #Configuration annotation on InfrastructureConfig. When using #Import, it works fine.
I don't want to use #Import because I want to mock my InfrastructureConfig like this :
#Configuration
public class TestConfig extends MainConfig {
#Override
public InfrastructureConfig infrastructureConfig() {
return mock(InfrastructureConfig.class);
}
}
Am I missing something or it is not supported ?
Thanks
When I first tried out Spring Java configuration I think I made the same assumption and was surprised when it didn't work.
I'm not sure this is the neatest way of solving this but I have used the following approach successfully.
To include that #Configuration class you can add this annotation to your MainConfig:
#ComponentScan(basePackages = "org.foo", includeFilters = {#Filter(filterType = ANNOTATION, value = CONFIGURATION)}, excludeFilters = {#Filter(filterType = ASSIGNABLE_TYPE, value = MainConfig)})
Since #Configuration classes are also candidates for component scanning this allows you to scan for all classes annotated with #Configuration. Since you're putting this annotation on MainConfig you need to exclude that with the ASSIGNABLE_TYPE filter since you'll get a circular reference.
I opened a Spring ticket SpringSource JIRA and they said that it is a known limitation and it is working as designed.

Convert Spring bean configuration into XML configuration

i am working on BIRT reporting tool. which is need to called by spring MVC.
i got one example from spring which is here. in this example, configuration is done via bean. can anyone help me convert this configuration in to xml based configuration ?
#EnableWebMvc
#ComponentScan({ "org.eclipse.birt.spring.core","org.eclipse.birt.spring.example" })
#Configuration
public class BirtWebConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/reports").setViewName("birtView");
}
#Bean
public BirtView birtView() {
BirtView bv = new BirtView();
// bv.setReportFormatRequestParameter("ReportFormat");
// bv.setReportNameRequestParameter("ReportName");
bv.setBirtEngine(this.engine().getObject());
return bv;
}
#Bean
public BeanNameViewResolver beanNameResolver() {
BeanNameViewResolver br = new BeanNameViewResolver();
return br;
}
#Bean
protected BirtEngineFactory engine() {
BirtEngineFactory factory = new BirtEngineFactory();
return factory;
}
}
I wants a similar configuration in xml file.
There's really no tool for extracting Spring annotations to Spring bean context xml file. You'll have to do it by hand, shouldn't be too hard as all the Spring annotations functionality can be duplicated into Spring context xml tags.
if you want to use spingmvc, so no need the configuration files.
my solution is that in Birt Script i call the impl java file like this :
sampleService = new Packages.com.example.warlock.service.SampleServiceImpl();
pojo = new Packages.com.example.warlock.entity.Sample();
iterator = sampleService.getSamples().iterator();
because my SampleService is a interface and SampleServiceImpl is impl java, the two java file are not config as #Bean.
At first i want to get the data from ModelMap but failed, so i skip the controller and straight to call Service, then final call the DAO to get the Data from DB

Resources