Vaadin i integracja ze Springiem 2.0.x

Żeby nie było, że jest to trudne, bo nie jest. Przedstawię tu metodę zintegrowania Vaadin ze Springiem w wersji 2.0. Z nowszym 2.5 jest to jeszcze łatwiejsze, ale nie dotykałem się tamtej wersji jeszcze i nie miałem okazji się pobawić. Zatem będzie trochę bardziej oldschoolowo, ale też ładnie. Tworzymy nowy projekt Vaadin za pomocą Mavena i dodajemy kilka informacji do pom.xml.

Listing 1. Springowo-Vaadinowy pom.xml



	4.0.0
	pl.koziolekweb.blog.vaadin
	vaadin-spring-integration-example
war
	1.0
	Vaadin Web Application

UTF-8
		2.0.3
	

	


				org.apache.maven.plugins
				maven-compiler-plugin
				
					1.6
					1.6
				
			

				org.mortbay.jetty
				maven-jetty-plugin
				6.1.19
				
					
						
							jetty.port
							23030
						
					
					9966
					vaadin-spring-integration-example
					25
					
						/vaadin-spring-integration-example
						
							src/main/webapp,${project.build.directory}/${project.build.finalName}
						
					
				
			

				org.apache.maven.plugins
				maven-eclipse-plugin
				2.8
				
					true
					true
				
				
					
						eclipse
clean
						
							clean
							eclipse
						
					
				
			
		
	
	
		
			vaadin-snapshots
			http://oss.sonatype.org/content/repositories/vaadin-snapshots/
			
				false
			
			
				true
			
		
	
	
		
			com.vaadin
			vaadin
			6.2.0
		
		
			org.springframework
			spring-core
			${spring.version}
		
		
			org.springframework
			spring-beans
			${spring.version}
		
		
			org.springframework
			spring-context
			${spring.version}
		
		
			org.springframework
			spring-web
			${spring.version}
		
		
			junit
			junit
			4.8.1
		
	

Teraz czas na wprowadzenie kilku zmian w web.xml. No niestety tu trzeba dołożyć kilka rzeczy. Wynika to bardziej z wykorzystania Springa, bo dla Vaadin wsio ryba.

Listing 2. Dodatkowe informacje w web.xml


...
	
contextConfigLocation
WEB-INF/applicationContext.xml
	

org.springframework.web.context.ContextLoaderListener
	
...

Czyli standardowo dokładamy listener kontekstu dla Springa i lokalizację applicationContext.xml. Sam plik applicationContext.xml wygląda tak:

Listing 3. applicationContext.xml naszej aplikacji





	

	

	


Będziemy robili taką samą aplikację jak poprzednio, ale tym razem ze Springiem na pokładzie.

Dodatkowe bajery

W tej wersji musimy stworzyć sobie małą fabryczkę, która będzie nam pośredniczyła w tworzeniu beanów. W przypadku wersji 2.5 można pominąć ten krok i dodać konfigurację z adnotacji.

Listing 4. SpringContextHelper

package pl.koziolekweb.blog.vaadin;

import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class SpringContextHelper {

	private ApplicationContext context;

	public SpringContextHelper(Application application) {
		ServletContext servletContext = ((WebApplicationContext) application
				.getContext()).getHttpSession().getServletContext();
		context = WebApplicationContextUtils
				.getRequiredWebApplicationContext(servletContext);
	}

	public  T getBean(Class beanClass, final String beanRef) {
		return beanClass.cast(context.getBean(beanRef));
	}

}

Lubię genericsy ;)

Aplikacja

Na koniec aplikacja. Nie podam wam tu klas implementujących interfejsy, bo chcę mieć co pokazać na WJUGu 20 kwietnia :) Gdzie oczywiście zapraszam :)

Listing 5. Efekt końcowy naszych prac

/*
 * Copyright 2009 IT Mill Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package pl.koziolekweb.blog.vaadin;

import java.awt.Color;
import java.awt.Image;
import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import pl.koziolekweb.blog.vaadin.beans.Manager;

import com.vaadin.Application;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.StreamResource.StreamSource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;

/**
 * The Application's "main" class
 */
@SuppressWarnings("serial")
public class MyVaadinApplication extends Application {
	private Window window;
	private SpringContextHelper helper;
	private Manager manager;
	private Image job;
	private Embedded image;
	private Button orderJobBtn;

	@Override
	public void init() {
		window = new Window("My Vaadin Application");
		setMainWindow(window);

		helper = new SpringContextHelper(this);
		manager = helper.getBean(Manager.class, "picassoMng");
		job = manager.getJob(Color.RED);
		orderJobBtn = new Button("Order Job");

		orderJobBtn.addListener(new ClickListener() {

			public void buttonClick(ClickEvent event) {

				StreamSource gallery = new StreamSource() {
					private ByteArrayOutputStream imagebuffer = null;

					public InputStream getStream() {
						try {
							imagebuffer = new ByteArrayOutputStream();
							ImageIO.write((RenderedImage) job, "png",
									imagebuffer);
							return new ByteArrayInputStream(imagebuffer
									.toByteArray());

						} catch (IOException e) {
							return null;
						}
					}
				};

				StreamResource imageresource = createStreamResource(gallery);
				if (image != null) {
					window.removeComponent(image);
				}
				image = new Embedded("Image title", imageresource);
				window.addComponent(image);

			}
		});

		window.addComponent(orderJobBtn);

	}

	private StreamResource createStreamResource(
			StreamResource.StreamSource imagesource) {
		return new StreamResource(imagesource, "myimage.png", this);
	}

}

Jak widać pierwszego beana pobieram wprost po nazwie. Można przyjąć, że w tym miejscu będzie tworzony też kontekst Spring Security. Oczywiście całość tylko raz przy starcie aplikacji.

No to by było na tyle.

Leave a Reply