Vaadin with Spring and Multiple Users - java

I have a really strange Problem with my new Vaadin Project.
If I start my Application and log in with a User, then switch the Browser and open the Site again, it seems that the Sessions will be shared. I have the same Content in both Windows.
I readed a few forum Posts about this Problem, all they say don´t open the App in the same Browser. Ok, i startet a VM, but, the same Problem. Or, remove all static variables from the context. I have done that, now using the ThreadLocal-Pattern.
I have absolutly no idea whats wrong. What I believe is that the Spring Context kills Vaadin, has anyone ever had this experience with Vaadin and Spring?
To bring Spring and Vaadin togehter I use the Spring Intgration Addon for Vaadin by Nicolas Frankel (https://vaadin.com/directory#addon/spring-integration)
I will post my Application Code for further investigation.
===================
The Vaadin Application Class:
public class MainApplication extends Application implements HttpServletRequestListener {
private static final long serialVersionUID = 2067470624065324231L;
private static ThreadLocal<MainApplication> threadLocal = new ThreadLocal<MainApplication>();
private Window mainWindow;
//Viewmanager
private ViewManager viewManager;
private Professor professor;
//DAO Classes and Bean Setter´s
ProfessorDAO professorDAO;
QuestionDAO questionDAO;
AnswerDAO answerDAO;
AnsweredDAO answeredDAO;
QRCodeDAO qrCodeDAO;
public void setProfessorDAO(ProfessorDAO professorDAO) {
System.out.println("Setting ProfessorDAO!");
System.out.println(professorDAO.toString());
this.professorDAO = professorDAO;
}
public void setQuestionDAO(QuestionDAO questionDAO) {
System.out.println("Setting QuestionDAO!");
System.out.println(questionDAO.toString());
this.questionDAO = questionDAO;
}
public void setAnswerDAO(AnswerDAO answerDAO) {
System.out.println("Setting AnswerDAO!");
System.out.println(answerDAO.toString());
this.answerDAO = answerDAO;
}
public void setAnsweredDAO(AnsweredDAO answeredDAO) {
System.out.println("Setting AnsweredDAO!");
System.out.println(answeredDAO.toString());
this.answeredDAO = answeredDAO;
}
public void setQrCodeDAO(QRCodeDAO qrCodeDAO) {
System.out.println("Setting QRCodeDAO!");
System.out.println(qrCodeDAO.toString());
this.qrCodeDAO = qrCodeDAO;
}
public ProfessorDAO getProfessorDAO() {
return professorDAO;
}
public QuestionDAO getQuestionDAO() {
return questionDAO;
}
public AnswerDAO getAnswerDAO() {
return answerDAO;
}
public AnsweredDAO getAnsweredDAO() {
return answeredDAO;
}
public QRCodeDAO getQrCodeDAO() {
return qrCodeDAO;
}
//Currently logged in Professor.
public Professor getProfessor() {
return professor;
}
public void setProfessor(Professor professor) {
this.professor = professor;
}
public static void setInstance(MainApplication application){
threadLocal.set(application);
}
public ViewManager getViewManager() {
return viewManager;
}
public void setViewManager(ViewManager viewManager) {
this.viewManager = viewManager;
}
public static MainApplication getInstance(){
return threadLocal.get();
}
public MainApplication() {
}
#Override
public void init() {
setInstance(this);
setTheme("crs");
mainWindow = new Window("CRS -- Classroom Response System");
setMainWindow(mainWindow);
viewManager = new ViewManager(mainWindow);
viewManager.switchScreen(LoginScreen.class.getName(), new LoginScreen());
//mainWindow = new MainWindow("CRS -- Classroom Response System");
//setMainWindow(mainWindow);
}
public void onRequestStart(HttpServletRequest request,
HttpServletResponse response) {
MainApplication.setInstance(this);
}
public void onRequestEnd(HttpServletRequest request,
HttpServletResponse response) {
threadLocal.remove();
}
The web.xml:
<display-name>CRSServer</display-name>
<context-param>
<description>
Vaadin production mode</description>
<param-name>productionMode</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<servlet-name>CRS</servlet-name>
<servlet-class>ch.frankel.vaadin.spring.SpringApplicationServlet</servlet-class>
<init-param>
<description>
Vaadin application class to start</description>
<param-name>applicationBeanName</param-name>
<param-value>cs.hm.edu.kreipl.crs.frontend.MainApplication</param-value>
</init-param>
<init-param>
<description>
Application widgetset</description>
<param-name>widgetset</param-name>
<param-value>cs.hm.edu.kreipl.crs.widgetset.CrsserverWidgetset</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>CRS</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring-config.xml</param-value>
</context-param>
The Spring Context
<context:component-scan base-package="cs.hm.edu.kreipl.crs" />
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url" value="jdbc:mysql://localhost:3306/crs"></property>
<property name="username" value="crs"></property>
<property name="password" value="password"></property>
</bean>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="annotatedClasses">
<list>
<value>cs.hm.edu.kreipl.crs.database.entity.Professor</value>
<value>cs.hm.edu.kreipl.crs.database.entity.Answer</value>
<value>cs.hm.edu.kreipl.crs.database.entity.Answered</value>
<value>cs.hm.edu.kreipl.crs.database.entity.Question</value>
<value>cs.hm.edu.kreipl.crs.database.entity.QuestionQRCode</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
<tx:annotation-driven/>
<!-- VAADIn Startup -->
<bean id="cs.hm.edu.kreipl.crs.frontend.MainApplication" class="cs.hm.edu.kreipl.crs.frontend.MainApplication">
<property name="answerDAO" ref="answerDAO" />
<property name="answeredDAO" ref="answeredDAO" />
<property name="professorDAO" ref="professorDAO" />
<property name="qrCodeDAO" ref="qrCodeDAO" />
<property name="questionDAO" ref="questionDAO" />
</bean>
<bean id="professorDAO" class="cs.hm.edu.kreipl.crs.database.implementation.ProfessorDAOImpl">
<constructor-arg>
<value>cs.hm.edu.kreipl.crs.database.entity.Professor</value>
</constructor-arg>
<property name="hibernateTemplate" ref="mySessionFactory"/>
</bean>
<bean id="questionDAO" class="cs.hm.edu.kreipl.crs.database.implementation.QuestionDAOImpl">
<constructor-arg>
<value>cs.hm.edu.kreipl.crs.database.entity.Question</value>
</constructor-arg>
<property name="hibernateTemplate" ref="mySessionFactory"/>
</bean>
<bean id="qrCodeDAO" class="cs.hm.edu.kreipl.crs.database.implementation.QRCodeDAOImpl">
<constructor-arg>
<value>cs.hm.edu.kreipl.crs.database.entity.QuestionQRCode</value>
</constructor-arg>
<property name="hibernateTemplate" ref="mySessionFactory"/>
</bean>
<bean id="answerDAO" class="cs.hm.edu.kreipl.crs.database.implementation.AnswerDAOImpl">
<constructor-arg>
<value>cs.hm.edu.kreipl.crs.database.entity.Answer</value>
</constructor-arg>
<property name="hibernateTemplate" ref="mySessionFactory"/>
</bean>
<bean id="answeredDAO" class="cs.hm.edu.kreipl.crs.database.implementation.AnsweredDAOImpl">
<constructor-arg>
<value>cs.hm.edu.kreipl.crs.database.entity.Answered</value>
</constructor-arg>
<property name="hibernateTemplate" ref="mySessionFactory"/>
</bean>
<bean id="deviceDAO" class="cs.hm.edu.kreipl.crs.database.implementation.DeviceDAOImpl">
<constructor-arg>
<value>cs.hm.edu.kreipl.crs.database.entity.Device</value>
</constructor-arg>
<property name="hibernateTemplate" ref="mySessionFactory"/>
</bean>
If you need any further classes please let me now.

I am using Vaadin + Spring but without Spring Integration Addon.
I think that the problem is that you are not creating a new Vaadin applicationBean for the new user that requests the application.
In my app, I pass the applicationBean in web.xml. My Vaadin application is annotated with:
Application Class
#Component(value = "appName")
#Scope(value = "session")
class AppName extends Application {
....
}
WEB.XML
<init-param>
<param-name>applicationBean</param-name>
<param-value>appName</param-value>
</init-param>
And for every new session Servlet returns new app.
In your web.xml you pass your vaadin application like this:
Your WEB.XML
<init-param>
<description>
Vaadin application class to start</description>
<param-name>applicationBeanName</param-name>
<param-value>cs.hm.edu.kreipl.crs.frontend.MainApplication</param-value>
</init-param>
So it returns every time the same app for all users. And that's what I think causes the problem.

Related

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'servicePersonalUrgenciasImplementacion'

So, I am pretty new to Spring MVC, and I think I'm having problems with configuration and I'm going crazy.
I've tried the solution here but either I'm unable to make it work or my mistake is something different
The error I'm getting is:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'servicioPersonalUrgenciasImplementacion': Unsatisfied dependency expressed through field 'dao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.modelo.dao.PersonalUrgenciasDAO' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
My components are:
Controller. in com.controladores package
#Controller
public class LoginController {
private ServicioPersonalUrgenciasLogin service;
#Autowired
public void setServicioPersonalUrgenciasLogin( ServicioPersonalUrgenciasLogin service) {
this.service = service;
}
#GetMapping("login")
public String login(Model model) {
PersonalUrgenciasLogin login = new PersonalUrgenciasLogin();
//Add customers to the model
model.addAttribute("login", login);
return "login";
}
...
}
Service interface and Service implementation, both in com.modelo.servicios
#Service
public interface ServicioPersonalUrgenciasLogin {
public boolean login(String username, String pwd) throws NoSuchAlgorithmException, UnsupportedEncodingException;
public void cambiarContrasenia(String username, String newpwd);
}
#Service
public class ServicioPersonalUrgenciasLoginImplementacion implements ServicioPersonalUrgenciasLogin {
#Autowired
private PersonalUrgenciasLoginDAO dao;
#Override
#Transactional
public boolean login(String username, String pwd) throws NoSuchAlgorithmException, UnsupportedEncodingException {
return dao.login(username, pwd);
}
#Override
#Transactional
public void cambiarContrasenia(String username, String newpwd) {
// I have to implement this,
}
}
DAO Interface and Implementation, both in com.modelo.dao package
I know this is not the way to implement a login, but I wanted something fast
public interface PersonalUrgenciasLoginDAO {
public boolean login(String username, String pwd) throws NoSuchAlgorithmException, UnsupportedEncodingException;
public void cambiarContrasenia(String username, String newpwd);
}
#Repository
public class PersonalUrgenciasLoginDAOImplementacion implements PersonalUrgenciasLoginDAO{
#Autowired
private SessionFactory factoria;
#Override
public boolean login(String username, String pwd) throws NoSuchAlgorithmException, UnsupportedEncodingException {
Session sesion = factoria.getCurrentSession();
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] hashInOne = md5.digest(pwd.getBytes("UTF-8"));
String hashMD5String = getString(hashInOne);
Query<String> query2 = sesion.createQuery(
"SELECT usuario FROM PersonalUrgencias WHERE contrasenia=: pwd AND usuario =:user", String.class);
query2.setParameter("user", username);
query2.setParameter("pwd", hashMD5String);
List<String> haLogueado = query2.getResultList();
return !haLogueado.isEmpty();
}
#Override
public void cambiarContrasenia(String username, String newpwd) {
// TODO Auto-generated method stub
}
private static String getString( byte[] bytes )
{
StringBuffer sb = new StringBuffer();
for( int i=0; i<bytes.length; i++ )
{
byte b = bytes[ i ];
String hex = Integer.toHexString((int) 0x00FF & b);
if (hex.length() == 1)
{
sb.append("0");
}
sb.append( hex );
}
return sb.toString();
}
My Entity. I know it is not wired, but I don't want it to be
And then, my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>triaje</display-name>
<absolute-ordering />
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
And this is my applicationContext.xml
I've tried just writting com in <context:component-scan...> too
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Add support for component scanning -->
<context:component-scan base-package="com, com.controladores, com.modelo.dao, com.modelo.entidades, com.modelo.servicios" />
<!-- Add support for conversion, formatting and validation support -->
<mvc:annotation-driven/>
<!-- Define Spring MVC view resolver -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Step 1: Define Database DataSource / connection pool -->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3316/trj?useSSL=false&serverTimezone=UTC" />
<property name="user" value="root" />
<property name="password" value="root" />
<!-- these are connection pool properties for C3P0 -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxIdleTime" value="30000" />
</bean>
<!-- Step 2: Setup Hibernate session factory -->
<bean id="factoria"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.modelo.entidades" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Step 3: Setup Hibernate transaction manager -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="factoria"/>
</bean>
<!-- Step 4: Enable configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="myTransactionManager" />
<!-- Add support for reading web resources: css, images, js... -->
<mvc:resources location="/resources/" mapping="/resources/**"></mvc:resources>
</beans>
I'm both grateful and sorry for anybody who has read through all of this

Spring #Scheduled does not work appropriate

I have a method that should run at some delay, make request to api and add the new photo to database. So, addPhoto is working fine. It can print some info, make a request, but doesn't add the photo. I checked the database and there are only one photo, that i added manually.
#Component("restBean")
#Service
public class RestService {
private static final String url1 = "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1324&camera=fhaz&api_key=DEMO_KEY";
private PhotoDao photoDao;
#Autowired
public void setPhotoDao(PhotoDao photoDao) {
this.photoDao = photoDao;
}
#Scheduled(fixedRate = 5000)
public void addPhoto() {
System.out.println("TIME HAS COME");
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Response> response = restTemplate
.getForEntity(url1,
Response.class);
Photo[] photos = response.getBody().getPhotos();
this.photoDao.save(photos[0]);
}
}
I have tested this method and all works except the last string. I checked that i get the response and can get the object from it.
this.photoDao.save(photos[0]);
That's my DAO class
#Repository
public class PhotoDaoImpl implements PhotoDao {
private static final Logger logger = LoggerFactory.getLogger(PhotoDaoImpl.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public void save(Photo photo) {
Session session = this.sessionFactory.getCurrentSession();
session.persist(photo);
logger.info("Photo successfully saved. Photo details: {}", photo);
}
#Override
public Photo findOne(int id) {
Session session = this.sessionFactory.getCurrentSession();
Photo photo = (Photo) session.load(Photo.class, new Integer(id));
logger.info("Photo successfully loaded. Photo details: {}", photo);
return photo;
}
#Override
#SuppressWarnings("unchecked")
public List<Photo> getAll() {
Session session = this.sessionFactory.getCurrentSession();
That's my spring xml configuration
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<!-- This helps in mapping the logical view names to directly view files under a certain pre-configured directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- Database Information -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/DayDatabase"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>net.yan.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- It register the beans in context and scan the annotations inside beans and activate them -->
<context:component-scan base-package="net.yan"/>
<!-- This allow for dispatching requests to Controllers -->
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<!-- PhotoDao and PhotoService beans -->
<bean id="photoDao" class="net.yan.dao.PhotoDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</bean>
<bean id="photoService" class="net.yan.service.PhotoServiceImpl">
<property name="photoDao" ref="photoDao"/>
</bean>
<bean id="restService" class="net.yan.service.RestService">
<property name="photoDao" ref="photoDao"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</bean>
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="restBean" method="addPhoto" fixed-delay="5000"/>
</task:scheduled-tasks>
<task:scheduler id="myScheduler"/>
UPD: To be clear, i have another method, that make request and add to database. It's in the same class that doesn't work.
#EventListener(ContextRefreshedEvent.class)
#Transactional
public void contextRefreshedEvent() {
if (this.photoDao.checkDataBase()) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Response> response = restTemplate
.getForEntity(url,
Response.class);
Photo[] photos = response.getBody().getPhotos();
this.photoDao.save(photos[0]);
}
}
UPD2: There's link to full project https://github.com/Kabowyad/Test-Project/tree/api-test/src/main/java/net/yan/service

Spring Application loads twice

I'm new to Spring and trying to get a example to work. But my application loads twice each time it starts. I think it could be a context problem because of my internet research and I have just one context.xml.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="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">
<context:annotation-config/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:environment.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:environment.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
<bean name="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />
<bean name="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="requestFactory" ref="requestFactory" />
</bean>
<bean name="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="10000" />
<property name="readTimeout" value="10000" />
</bean>
<bean name="httpClient" class="org.apache.http.client.HttpClient" factory-bean="requestFactory" factory-method="getHttpClient"/>
<bean name="TraderApplication" class="net.mrmoor.TraderApplication"/>
<bean name="API" class="com.iggroup.api.API"/>
<bean name="LightStreamerComponent" class="com.iggroup.api.streaming.LightStreamerComponent"/>
</beans>
My code of the TraderApplication Class is:
... skipped imports ....
#SpringBootApplication
public class TraderApplication implements CommandLineRunner{
private static final Logger log = LoggerFactory.getLogger(TraderApplication.class);
#Autowired
protected ObjectMapper objectMapper;
#Autowired
private API api;
#Autowired
private LightStreamerComponent lightStreamerComponent = new LightStreamerComponent();
private AuthenticationResponseAndConversationContext authenticationContext = null;
private ArrayList<HandyTableListenerAdapter> listeners = new ArrayList<HandyTableListenerAdapter>();
public static void main(String args[]) {
SpringApplication.run(TraderApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
try {
if (args.length < 2) {
log.error("Usage:- Application identifier password apikey");
System.exit(-1);
}
String identifier = args[0];
String password = args[1];
String apiKey = args[2];
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/public-api-client-spring-context.xml");
TraderApplication app = (TraderApplication) applicationContext.getBean("TraderApplication");
app.run(identifier, password, apiKey);
} catch (Exception e) {
log.error("Unexpected error:", e);
}
}
You mention in your comments above you got this working by removing SpringApplication.run(TraderApplication.class, args); but this would be removing spring-boot from your application so I'm going to assume since your question has a tag of [spring-boot] that this is not what you wanted. So here is an alternative way that you can configure beans using your xml.
#ImportResource({"classpath*:public-api-client-spring-context.xml"}) //Proper way to import xml in Spring Boot
#SpringBootApplication
public class TraderApplication implements CommandLineRunner {
...code you had before goes here
#Autowired
TraderApplication app;
#Override
public void run(String... args) throws Exception {
.. your parsing logic here
app.run(identifier, password, apiKey); //Now uses the autowired instance
}
}
You didn't list your pom.xml or build.gradle but it's important to remember that components you have registered in your context xml may be automatically configured in Spring Boot and you may not need to register them yourself in your xml.(Depending on which items you have starters for in your build file)

Spring MVC & Freemarker/Velocity

I've got a problem with Freemarker's and Velocity's view resolver (not running at same moment) - both of them don't see Spring's session beans. Spring's InternalResourceViewResolver works good.
Some code:
<context:component-scan base-package="com.revicostudio.web" />
<mvc:annotation-driven />
<bean id="userSession" class="com.revicostudio.web.session.UserSession" scope="session" />
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/jsp/" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="layoutUrl" value="layout.jsp"/>
<property name="suffix" value=".jsp" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeRequestAttributes" value="true" />
<property name="requestContextAttribute" value="rc" />
</bean>
In jsp:
${userSession}<br /> <!-- Null if Freemarker's view resolver active, session object if Spring's resolver active -->
${error}<br /> <!-- Normal request attribute, put to map, that works good in both resolvers -->
IndexController:
#Controller
#RequestMapping("/index")
public class IndexController {
#RequestMapping(method=RequestMethod.GET)
public String getIndex(Model model) {
return "index";
}
#ModelAttribute("userRegisterCredentials")
public UserRegisterCredentials getUserRegisterCredentials() {
return new UserRegisterCredentials();
}
#ModelAttribute("userLoginCredentials")
public UserLoginCredentials getUserLoginCredentials() {
return new UserLoginCredentials();
}
}
1.You should annotate controller to point out which model attribute should be exposed in a session
2.In freemarker, access to session attrs is done by a freemarker session wrapper.
Short example below, based on Your code:
#Controller
#SessionAttributes("userRegisterCredentials")
#RequestMapping("/index")
public class IndexController {
#RequestMapping(method=RequestMethod.GET)
public String getIndex(Model model) {
return "index";
}
#ModelAttribute("userRegisterCredentials")
public UserRegisterCredentials getUserRegisterCredentials() {
return new UserRegisterCredentials();
}
}
On the ftl side:${Session.userRegisterCredentials.someStringField}

Spring MVC RESTful multiple view - 404 Not Found

I have a web app which has JSPs as a view. But now I am trying to implement a RESTful in the same web app. I created a new controller, where will be my RESTful(I am not sure if it makes sense yet).
I have found some examples by internet and I have been trying to make my RESTful following these examples.
When I access my RESTful URL it return me 404 Not Found. I took a look at in some questions similars here in stackoverflow and tried to change some XML configurations, but it does not works, so far.
When I access:
URL: localhost:8080/restfultest/rest/suggestions/11
returns me: 404.
When I access:
URL: localhost:8080/restfultest/loginForm
Returns me the correct JSP page.
I think, maybe I need to set up the XML to be compatible with both kinds, RESTful and a common web app, but I am not sure, and I do not know exactly how to do it.
Thanks and follows my codes:
My web.xml
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
spring-context.xml
<context:component-scan base-package="com.restfultest." />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="contentType" value="application/json"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="jsonMessageConverter"/>
</util:list>
</property>
</bean>
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:interceptors>
<bean class="com.restfultest.interceptor.AutorizadorInterceptor"></bean>
<bean class="com.restfultest.interceptor.ConnectionInterceptor"></bean>
</mvc:interceptors>
<mvc:resources location="/resources/" mapping="/resources/**" />
Controller
public class SuggestionController {
#Autowired
private SuggestionService suggestionService;
#Autowired
private View view;
private static final String DATA_FIELD = "data";
private static final String ERROR_FIELD = "error";
private static final String CONTENT_RANGE_HEADER = "Content-Range";
private static final String ACCEPT_JSON = "Accept=application/json";
#RequestMapping(value = "/rest/suggestions/{suggestionId}", method = RequestMethod.GET, headers=ACCEPT_JSON)
public ModelAndView getSuggestion(#PathVariable("suggestionId") String suggestionId) {
Suggestion suggestion = null;
if (isEmpty(suggestionId) || suggestionId.length() < 5) {
String sMessage = "Error invoking getSuggestion - Invalid suggestion Id parameter";
return createErrorResponse(sMessage);
}
try {
suggestion = suggestionService.getSuggestionById(suggestionId);
} catch (Exception e) {
String sMessage = "Error invoking getSuggestion. [%1$s]";
return createErrorResponse(String.format(sMessage, e.toString()));
}
return new ModelAndView(view, DATA_FIELD, suggestion);
}
private ModelAndView createErrorResponse(String sMessage) {
return new ModelAndView(view, ERROR_FIELD, sMessage);
}
public static boolean isEmpty(String s_p) {
return (null == s_p) || s_p.trim().length() == 0;
}
The problem is your SuggestionController should have a #Controller annotation on it so Spring will treat it as a Controller (it should also be in the com.restfultest package).
Now I'm not sure if this matters butin the spring-context.xml where you have
<context:component-scan base-package="com.restfultest." />
I've never seen it with a dot at the end. So you might consider removing it, but it might not make a difference.

Categories