Setting up Vaadin and Spring 3 - Autowiring fails (annotations) - spring

I'm having some trouble using the #Autowire annotation of spring 3 in a vaadin application.
I have made a tiny test project with just a button which executes a method in an autowired service class.
I'm getting a NullPointerException when I click the button, because the service is never injected.
I have annotated the service with #Service("calculationService")
This is my application class:
package vaadinBaas;
// imports
public class MyVaadinApplication extends Application {
private Window window;
private CalculationService calculationService;
#Autowired
public void setCalculationService(CalculationService calculationService) {
this.calculationService = calculationService;
}
#Override
public void init() {
window = new Window("Show me the magic");
setMainWindow(window);
Button button = new Button("Click Me");
button.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
window.addComponent(new Label(String.valueOf(calculationService.multiply(10, 10))));
}
});
window.addComponent(button);
}
}
This is my spring application context:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ct="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<ct:component-scan base-package="vaadinBaas" />
<ct:annotation-config />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
</beans>
And finally my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Vaadin Web Application</display-name>
<context-param>
<description>Vaadin production mode</description>
<param-name>productionMode</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<servlet-name>Vaadin Application Servlet</servlet-name>
<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>vaadinBaas.MyVaadinApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Vaadin Application Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
</web-app>
Am I missing something obvious here?

Try annotating MyVaadinApplication with Component annotation. Since MyVaadinApplication is not considered as spring managed class the Autowire didnt work for you. Also you need to load the bean definition xml using ClassPathXmlApplicationContext and try calling getBean(MyVaadinApplication.class) so that all the autowiring happens automatically

Related

How to use listener-class in spring boot 2.2.1 RELEASE

Migrating Spring web project into spring boot application with following versions
Spring version:-4.1.7
Spring boot:2.2.1 RELEASE
part of migration i need to remove src/main/web-app folder.In this folder i have two files
dispatcher-servlet.xml
web.xml
dispatcher-servlet
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.data.services" />
<bean id="systemPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<mvc:interceptors>
<bean class="com.data.services.interceptors.RequestLogInterceptor" />
</mvc:interceptors>
</beans>
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
metadata-complete="true" version="3.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>XERService</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/conf/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>30000</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>xerwebapp.root</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>com.data.services.configuration.ServiceContextListener</listener-class>
</listener>
</web-app>
ServiceContextListener
#WebListener("Service context listener")
public class ServiceContextListener implements ServletContextListener
{
public static final Logger LOG = Logger.getLogger("XERService");
/**
* Context initializer. This method sets the root folder for the log4j
*/
#Override
public void contextInitialized(ServletContextEvent event)
{
}
#Override
public void contextDestroyed(ServletContextEvent event)
{
try
{
LoggingPropertyHandler.clear();
if (XFabSiteConfigManager.getInstance().getRequesterConfigInfo() != null)
{
XFabFactory.getXfabInstance().unInitializeRequester();
}
}
catch (Exception exception)
{
LOG.warn("Exception while uninitializing Requestor", exception);
}
}
}
RequestLogInterceptor
#Component
public class equestLogInterceptor extends HandlerInterceptorAdapter
{
/**
* Method to add the Audit user in the log
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
String auditUser = request.getHeader(RequestParameterConstants.AUDIT_USER);
if (auditUser == null)
{
auditUser = "";
}
LoggingPropertyHandler.addAuditUserName(auditUser);
return true;
}
}
How can we include following listener in spring boot
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>com.data.services.configuration.ServiceContextListener</listener-class>
</listener>
Is there any simplest mechanism available in spring boot.
You can create the Listener bean like this:
// Register ServletContextListener
#Bean
public ServletListenerRegistrationBean<ServletContextListener> listenerRegistrationBean() {
ServletListenerRegistrationBean<ServletContextListener> bean =
new ServletListenerRegistrationBean<>();
bean.setListener(new MyServletContextListener());
return bean;
}

Spring 4.2.1 RestController tried to return template instead return JSON

I tried to create a Spring Rest Controller, based on this example i create a controller like this.
DeveloperRestController.java
#RestController
public class DeveloperRestController {
#RequestMapping("/developer/list")
public Developer index() {
Developer developer = new Developer("Developername", "developer#yahoo.com");
return developer;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!--Here we specify about the DispatcherServlet class in the Web Deployment Descriptor-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
</web-app>
dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.developerdata.controller" />
<context:annotation-config />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
But it shows 404 page not found, seems that spring tried to load a template...
Result:
Error 404 /WEB-INF/jsp/developer/list.jsp
what should i do?
Seems like you have a configuration issue. The sample you are basing yours on is spring boot based. So it handles the configuration for you. To get yours working you will need to add jackson to the classpath. If you are using maven then:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.2</version>
</dependency>
Then you need to alter your spring config to include:
<mvc:annotation-driven />
From the spring documentation:
The above registers a RequestMappingHandlerMapping, a
RequestMappingHandlerAdapter, and an ExceptionHandlerExceptionResolver
(among others) in support of processing requests with annotated
controller methods using annotations such as #RequestMapping,
#ExceptionHandler, and others.
This also then enables the MappingJackson2HttpMessageConverter if jackson 2 is in your classpath.
References:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-config-enable
https://spring.io/guides/gs/rest-service/
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/ (This one seems more appropriate for you to get started based on your problem)
With #ResponseBody, Spring will handle the JSON you need. Jackson
library is required too.
#RestController
public class DeveloperRestController {
#RequestMapping("/developer/list")
public #ResponseBody Developer index() {
Developer developer = new Developer("Developername", "developer#yahoo.com");
return developer;
}
}

The requested resource is not available error in spring mvc project

I got an error as follows :
Status report
message: /SBC/loginform.html
description :The requested resource is not available.
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/Views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>OpticareVisionHouse</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/forms/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/resources/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
</web-app>
-------------------------------------------------
LoginController.java
#Controller
#RequestMapping("loginform.html")
public class LoginController {
#Autowired
public LoginService loginService;
#RequestMapping(method = RequestMethod.GET)
public String showForm(Map model) {
LoginForm loginForm = new LoginForm();
model.put("loginForm", loginForm);
System.out.print("controller calls1");
return "loginform";
}
#RequestMapping(method = RequestMethod.POST)
public String processForm(#Valid LoginForm loginForm, BindingResult result,
Map model) {
System.out.print("controller calls2");
if (result.hasErrors()) {
return "loginform";
}
/*
String userName = "UserName";
String password = "password";
loginForm = (LoginForm) model.get("loginForm");
if (!loginForm.getUserName().equals(userName)
|| !loginForm.getPassword().equals(password)) {
return "loginform";
}
*/
boolean userExists = loginService.checkLogin(loginForm.getUserName(),
loginForm.getPassword());
if(userExists){
model.put("loginForm", loginForm);
return "loginsuccess";
}else{
result.rejectValue("userName","invaliduser");
return "loginform";
}
}
------------------------------------------------
index.jsp
<% response.sendRedirect("loginform.html"); %>
------------------------------------------------
index.jsp is there at webContent.
loginform.jsp is at webContent->web-Inf ->Views
Your dispatcherServlet is mapping urls like: /forms/* to the spring servlet.
You are requesting a url like: /SBC/loginform.html
This request will never go to the spring servlet. You have to access: /{your app context}/forms/loginform.html in order to go to the spring url mapped. Your app context seems to be "SBC", so it will be something like: /SBC/forms/loginform.html
Another way is change the Servlet mapping to:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
This way, every request on your app context /SBC/* will be routed to the spring servlet.
With this configuration, you should be able to access your controller with: /SBC/loginform.html

Vaadin and Spring integration - #Inject doesn't work

I'm trying to integrate Vaadin with Spring. In my main Vaadin application class I have:
public class MyVaadinApplication extends UI {
#Inject
private PrivatePersonBo privatePersonBo;
#Override
public void init(VaadinRequest request) {
Layout layout = new FormLayout();
layout.setCaption("New Private Person");
setContent(layout);
ApplicationContext appContext = new ClassPathXmlApplicationContext("resources/spring/Context.xml");
appContext.getBean(MyVaadinApplication.class);
PrivatePersonBo privatePersonBo = (PrivatePersonBo) appContext.getBean("privatePersonBo");
PrivatePerson existingEmployee = privatePersonBo.findByName("TestUserName");
}
}
If I get bean from context directly I recieve bean, however If I comment line which recieves bean from appContext then #Inject annotation doesn't work and I get NullPointerException. My deployment descriptor is below:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:resources/spring/Context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>VaadinApplicationServlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>pl.adamsalata.MyVaadinApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>VaadinApplicationServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Any suggestions please?
You can integrate Vaadin 7 with Spring in two simple steps:
1) Create a UIProvider that lookup UIs in spring context:
public class SpringUIProvider extends DefaultUIProvider {
#Override
public UI createInstance(UICreateEvent event) {
ApplicationContext ctx = WebApplicationContextUtils
.getWebApplicationContext(VaadinServlet.getCurrent().getServletContext());
return ctx.getBean(event.getUIClass());
}
}
2) Declare the UIProvider in web.xml:
<context-param>
<param-name>UIProvider</param-name>
<param-value>org.example.SpringUIProvider</param-value>
</context-param>
And remember to use prototype scope for UI classes.
If you want to integrate Vaadin with Spring then use #Configurable feature. Then all instantiated objects (even if you create them using new MyObject() code) will be integrated with Spring context. You can find more details about such setup in Spring documentation: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-using-aspectj

Spring Mobile inside AuthenticationFailureHandler not found

I am development success and failure handlers in Spring Security.
Depends device type I must show one html view or send one json response. To this purpose I use Spring Mobile, but when I create Device object with HtttpServletRequest not found. Some idea?
web.xml
<filter>
<filter-name>deviceResolverRequestFilter</filter-name>
<filter-class>org.springframework.mobile.device.DeviceResolverRequestFilter</filter-class>
</filter>
ApplicationContext.xml
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
Class
public class AuthFailureHandler implements AuthenticationFailureHandler{
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException ae) throws IOException, ServletException {
Device device = DeviceUtils.getCurrentDevice(request);
if(device.isNormal()){
response.sendRedirect(response.encodeRedirectURL("./userNoAuth"));
} else {
response.sendRedirect(response.encodeRedirectURL("./rest/userNoAuth"));
}
}
}
Error
java.lang.NullPointerException at com.myapp.security.handler.AuthFailureHandler.onAuthenticationFailure(AuthFailureHandler.java:19)
UPDATE:
I am change .getCurrentDevice(HttpServletRequest) method to getRequiredCurrentDevice(HttpServletRequest).
Now I get this error.
java.lang.IllegalStateException: No currenet device is set in this request and one is required - have you configured a DeviceResolvingHandlerInterceptor?
Verify your web.xml contains a filter-mapping for the deviceResolverRequestFilter. The following is a working example from the Spring Mobile Samples repository. Hope that helps!
https://github.com/SpringSource/spring-mobile-samples/tree/master/lite-device-resolver-xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Use the DeviceResolverRequestFilter OR the DeviceResolverHandlerInterceptor in the servlet-context.xml -->
<filter>
<filter-name>deviceResolverRequestFilter</filter-name>
<filter-class>org.springframework.mobile.device.DeviceResolverRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>deviceResolverRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

Resources