iT邦幫忙

DAY 27
1

Java Web的設計與應用系列 第 27

Day27 Vaadin 探討前後端設計實例

  • 分享至 

  • xImage
  •  

準備技術:

  1. Vaadin
  2. JPA
  3. Vaadin UI

網站的前後端,看一個Vaadin實例。

  1. 後端,結合JPA,採用H2 DB。

    public class Backend {

     static SimpleJDBCConnectionPool connectionPool = setupConnectionPoolAndCreateMockupDatabase();
     static public final String titleId = "TITLE";
     static public final String textId = "TEXT";
    
     public static Container getNotesContainer() {
     	try {
     		if (connectionPool == null)
     			return null;
     		return new SQLContainer(new TableQuery("notes", connectionPool));
     	} catch (SQLException e) {
     		e.printStackTrace();
     		return null;
     	}
     }
    
     public static void commitChanges(Container modifiedConteiner) {
     	try {
     		((SQLContainer) modifiedConteiner).commit();
     	} catch (UnsupportedOperationException e) {
     		e.printStackTrace();
     	} catch (SQLException e) {
     		e.printStackTrace();
     	}
     }
    
     private static SimpleJDBCConnectionPool setupConnectionPoolAndCreateMockupDatabase() {
     	try {
     		SimpleJDBCConnectionPool pool = new SimpleJDBCConnectionPool(
     				"org.h2.Driver", "jdbc:h2:mem:notes", "sa", "sa");
     		Connection c = pool.reserveConnection();
     		try {
     			c.createStatement().executeQuery("select * from notes");
     		} catch (SQLException e) {
     			createTable(c);
     			initDatabaseWithRandomData(c);
     		} finally {
     			pool.releaseConnection(c);
     		}
     		return pool;
     	} catch (SQLException e) {
     		e.printStackTrace();
     		return null;
     	}
     }
    
     // Database contains just one table: notes with id, title and text columns
     private static void createTable(Connection c) throws SQLException {
     	c.createStatement().executeUpdate(
     			"create table notes(id long primary key, " + titleId
     					+ " varchar(100), " + textId + " varchar(4000))");
     }
    
     private static void initDatabaseWithRandomData(Connection connection)
     		throws SQLException {
     	for (int i = 0; i < 500; i++) {
     		PreparedStatement p = connection
     				.prepareStatement("insert into notes values (?,?,?)");
     		p.setLong(1, i);
     		p.setString(2, generateRandomTitle((int) (Math.random() * 5 + 1)));
     		p.setString(3, generateRandomHTML((int) (Math.random() * 250 + 1)));
     		p.executeUpdate();
     	}
     	connection.commit();
     }
    
     private static String generateRandomHTML(int minimumNumberOfWords) {
     	StringBuffer sb = new StringBuffer();
     	while (minimumNumberOfWords > 0) {
     		sb.append("<h2>");
     		int len = (int) (Math.random() * 4) + 1;
     		sb.append(generateRandomTitle(len));
     		sb.append("</h2>");
     		minimumNumberOfWords -= len;
     		int paragraphs = 1 + (int) (Math.random() * 3);
     		while (paragraphs-- > 0 && minimumNumberOfWords > 0) {
     			sb.append("<p>");
     			len = (int) (Math.random() * 40) + 3;
     			sb.append(generateRandomText(len));
     			sb.append("</p>");
     			minimumNumberOfWords -= len;
     		}
     	}
     	return sb.toString();
     }
    
     private static String generateRandomTitle(int numberOfWords) {
     	StringBuffer sb = new StringBuffer();
     	int len = (int) (Math.random() * 4) + 1;
     	sb.append(generateRandomWords(len, true));
     	while (--numberOfWords > 0) {
     		len = (int) (Math.random() * 4) + 1;
     		sb.append(' ');
     		sb.append(generateRandomWords(len, false));
     	}
     	return sb.toString();
     }
    
     private static String generateRandomWords(int numberOfParts,
     		boolean capitalized) {
     	String[] part = { "ger", "ma", "isa", "app", "le", "ni", "ke", "mic",
     			"ro", "soft", "wa", "re", "lo", "gi", "is", "acc", "el", "tes",
     			"la", "ko", "ni", "ka", "so", "ny", "mi", "nol", "ta", "pa",
     			"na", "so", "nic", "sa", "les", "for", "ce" };
     	StringBuffer sb = new StringBuffer();
     	for (int i = 0; i < numberOfParts; i++) {
     		String p = part[(int) (Math.random() * part.length)];
     		if (i == 0 && capitalized)
     			p = Character.toUpperCase(p.charAt(0)) + p.substring(1);
     		sb.append(p);
     	}
     	return sb.toString();
     }
    
     private static String generateRandomText(int words) {
     	StringBuffer sb = new StringBuffer();
     	int sentenceWordsLeft = 0;
     	while (words-- > 0) {
     		if (sb.length() > 0)
     			sb.append(' ');
     		if (sentenceWordsLeft == 0 && words > 0) {
     			sentenceWordsLeft = (int) (Math.random() * 15);
     			sb.append(generateRandomWords(1 + (int) (Math.random() * 3),
     					true));
     		} else {
     			sentenceWordsLeft--;
     			sb.append(generateRandomWords(1 + (int) (Math.random() * 3),
     					false));
     			if (words > 0 && sentenceWordsLeft > 2 && Math.random() < 0.2)
     				sb.append(',');
     			else if (sentenceWordsLeft == 0 || words == 0)
     				sb.append('.');
     		}
     	}
     	return sb.toString();
     }
    

    }

  2. Component。

    import com.vaadin.data.Item;
    import com.vaadin.data.fieldgroup.FieldGroup;
    import com.vaadin.data.fieldgroup.PropertyId;
    import com.vaadin.ui.CustomComponent;
    import com.vaadin.ui.RichTextArea;
    import com.vaadin.ui.TextField;
    import com.vaadin.ui.VerticalLayout;

    public class NoteEditor extends CustomComponent {

     @PropertyId(Backend.titleId)
     TextField title = new TextField();
     @PropertyId(Backend.textId)
     RichTextArea text = new RichTextArea();
    
     public NoteEditor() {
     	VerticalLayout layout = new VerticalLayout();
     	setCompositionRoot(layout);
    
     	layout.addComponent(title);
     	layout.addComponent(text);
     	setSizeFull();
     	layout.setSizeFull();		
     	title.setWidth("100%");
     	text.setSizeFull();
     	layout.setExpandRatio(text, 1.0f);
     }
    
     public void setNote(Item note) {
     	FieldGroup g = new FieldGroup(note);
     	g.bindMemberFields(this);
     	g.setBuffered(false);
     }
    

    }

  3. 前端的UI。

    import javax.servlet.annotation.WebServlet;

    import com.vaadin.annotations.Theme;
    import com.vaadin.annotations.VaadinServletConfiguration;
    import com.vaadin.event.ItemClickEvent;
    import com.vaadin.event.ItemClickEvent.ItemClickListener;
    import com.vaadin.server.VaadinRequest;
    import com.vaadin.server.VaadinServlet;
    import com.vaadin.ui.Button;
    import com.vaadin.ui.Button.ClickEvent;
    import com.vaadin.ui.Button.ClickListener;
    import com.vaadin.ui.Table.ColumnHeaderMode;
    import com.vaadin.ui.HorizontalSplitPanel;
    import com.vaadin.ui.Label;
    import com.vaadin.ui.Table;
    import com.vaadin.ui.UI;
    import com.vaadin.ui.VerticalLayout;

    @SuppressWarnings("serial")
    @Theme("vaadinrpcdemo")
    public class VaadinrpcdemoUI extends UI {

     @WebServlet(value = "/*", asyncSupported = true)
     @VaadinServletConfiguration(productionMode = false, ui = VaadinrpcdemoUI.class)
     public static class Servlet extends VaadinServlet {
     }
    
     Table notes = new Table();
     NoteEditor editor = new NoteEditor();
     Button saveButton = new Button("Save");
    
     @Override
     protected void init(VaadinRequest request) {
     	buildLayout();
     	wireUp();
     	connectToBackend();
     }
     private void connectToBackend() {
     	notes.setContainerDataSource(Backend.getNotesContainer());
     	notes.setVisibleColumns(new String[] { Backend.titleId });
     	notes.setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
     }
    
     private void wireUp() {
     	notes.addItemClickListener(new ItemClickListener() {
     		public void itemClick(ItemClickEvent event) {
     			editor.setNote(event.getItem());	
     		}
     	});
    
     	saveButton.addClickListener(new ClickListener() {
     		public void buttonClick(ClickEvent event) {
     			Backend.commitChanges(notes.getContainerDataSource());
     		}
     	});
     }
    
     private void buildLayout() {
     	HorizontalSplitPanel split = new HorizontalSplitPanel();
     	VerticalLayout right = new VerticalLayout();
    
     	setContent(split);
     	split.addComponent(notes);
     	split.addComponent(right);
    
     	right.addComponent(editor);
     	right.setSizeFull();
     	right.setExpandRatio(editor, 1.0f);
     	right.setMargin(true);
     	right.setSpacing(true);
     	right.addComponent(saveButton);
    
     	notes.setSizeFull();
     }
    

    }

  4. Vaadin RPC。

  5. 該實例的架構,參考文件2

  6. 網站運行結果。

參考資料:

  1. Vaadin 官網
  2. Client-Server Hybrid Apps with Vaadin

Day 27 結束


上一篇
Day26 Vaadin 探討Serialize and DeSerialize原理
下一篇
Day28 Vaadin RPC的理論與實做
系列文
Java Web的設計與應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言