JSF 学习之 编写自定义控件(第二部分)
2013-01-14 19:54
281 查看
2007-11-30 20:03
自定义控件(custom tag)的使用
jsp页面代码:看到灰色背景部分代码了吗?
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://hi.baidu.com/widebright" prefix="widebright" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<f:view locale="zh">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="styles.css" rel="stylesheet" type="text/css" />
<title>"widebright的留言板"</title>
</head>
<widebright:userBar id="usrbar" urls=",新浪,1;"/>
<widebright:userBar id="test" urls="#{tableExampleBean.urls}" userlogin = "true" binding ="#{tableExampleBean.userBar1}" userleave="#{tableExampleBean.UserBar_Click}"/>
<body>
<h:form>
<div class="tit">添加留言:</div>
<table width="620" border="0" cellspacing="5" cellpadding="0">
<tr>
<td class="f14">姓 名:</td>
<td>
<h:inputText value="#{tableExampleBean.inputAuthor}" binding="#{tableExampleBean.username}" style="width:220px" maxlength="49" tabindex="1" required="true"> </h:inputText>
</td>
</tr>
<tr>
<td>网址或邮箱:</td>
<td><h:inputText value="#{tableExampleBean.inputURL}" style="width:360px" maxlength="128" tabindex="2"> </h:inputText>(选填)</td>
</tr>
<tr>
<td valign="top">内 容:</td>
<td><h:inputTextarea value="#{tableExampleBean.inputContent}"style="width:520px;height:155px" tabindex="3"> </h:inputTextarea>
</td>
</tr>
<tr>
<td valign="top"> </td>
<td valign="top">
<h:commandButton value="添加留言" action = "#{tableExampleBean.Button_onClick}"tabindex="5" id="btn_ok" type="submit"> </h:commandButton>
<h:outputText value= "#{tableExampleBean.outputError}" style="color: #FF0000"></h:outputText> </td>
</tr>
</table>
<div style = "width:100%;height:30px;background-color: #ddffdd;"> JSTL循环实现的表格,模仿百度空间留言板</div>
<div id = "Message">
<c:forEach var = "varMessage" items = "${tableExampleBean.messages}" varStatus="status">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="item">
<tr>
<td valign="top" class="index" width="5%"> ${varMessage.number}</td>
<td align="center" valign="top" width="10%">
<div class="user" style="overflow:hidden;">
<a href="http://hi.baidu.com/widebright" target='_blank' title=“http://hi.baidu.com/widebright”>
<img border="0" src="widebright.jpg"><br/>
${varMessage.user} </a>
</div>
</td>
<td class="cnt" style="padding-left:20px;">
<span class="date">${varMessage.time} </span>
<div class="desc" style="overflow:hidden;"> ${varMessage.description}</div>
</td>
</tr>
</table>
<div class="line"> </div>
</c:forEach>
</div>
<div style = "width:100%;height:30px;background-color: #ddffdd;"> JSF中h:dataTable 标签实现的表格</div>
<h:dataTable value="#{tableExampleBean.messages}" var="messageRow" border="1" rowClasses="ROW1,ROW2" headerClass="HEADING">
<h:column>
<f:facet name="header">
<f:verbatim>序号</f:verbatim>
</f:facet>
<h:outputText value="#{messageRow.number}"/>
</h:column>
<h:column>
<f:facet name="header">
<f:verbatim>作者</f:verbatim>
</f:facet>
<h:outputText value="#{messageRow.user}"/>
</h:column>
<h:column>
<f:facet name="header">
<f:verbatim>内容</f:verbatim>
</f:facet>
<h:outputText value="#{messageRow.time}"/>
<f:verbatim> <br> </f:verbatim>
<h:outputText value="#{messageRow.description}"/>
</h:column>
</h:dataTable>
</h:form>
</body>
</html>
</f:view>
页面后台代码:控件的banding属性很有意思的,注意到了吗?
package widebright;
import java.util.Collection;
import java.util.ArrayList;
import java.sql.*;
public class TableExampleBean {
// private Collection <Message> messages; //所有的留言
private Collection<Message> messages; // 所有的留言
//inputText输入框控件的值
private String inputAuthor;
private String inputURL;
private String inputContent;
private String outputError; //错误提示
private ArrayList<URL> urls = null;
private UIUserBar userBar1;
private javax.faces.component.UIInput username;
public TableExampleBean() {
messages = new ArrayList<Message>();
messages.add(new Message("0", "widebright", "好好学习,天天向上", "2007-11-5"));
messages.add(new Message("2", "widebright", "好好学习,天天向上", "2007-11-5"));
messages.add(new Message("3", "widebright", "好好学习,天天向上", "2007-11-5"));
urls = new ArrayList<URL>();
urls.add(new URL("http://www.163.com","网易", 1) );
urls.add(new URL("http://www.sina.com.cn","新浪", 2) );
}
public void setInputAuthor(String author){
this.inputAuthor = author;
}
public String getInputAuthor(){
return this.inputAuthor ;
}
public void setInputURL(String url){
this.inputURL= url;
}
public String getInputURL(){
return this.inputURL ;
}
public void setInputContent(String content){
this.inputContent= content;
}
public String getInputContent(){
return this.inputContent ;
4000
}
public void setOutputError(String error){
this.outputError= error;
}
public String getOutputError(){
return this.outputError ;
}
public void setMessages(Collection<Message> messages) {
this.messages = messages;
}
public Collection<Message> getMessages() {
Connection conn = null;
// assume that conn is an already created JDBC connection
Statement stmt = null;
ResultSet rs = null;
try {
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
return this.messages;
}
try {
// The JDBC URL format for MySQL Connector/J is as follows, with items in square brackets ([, ]) being optional:
// jdbc:mysql://[host][,failoverhost...][:port]/[database]
// [?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...
// If the hostname is not specified, it defaults to 127.0.0.1. If the port is not specified, it defaults to 3306, the default port number for
// MySQL servers.
// jdbc:mysql://[host:port],[host:port].../[database]
// [?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...
// If the database is not specified, the connection will be made with no default database
//The properties are listed in the following tables.
// user The user to connect as all versions
// password The password to use when connecting
//
conn = DriverManager.getConnection("jdbc:mysql://localhost/widebright?user=root&password=");
// Do something with the Connection
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT message.ID, Author,Time,Description ,URL FROM widebright.message order by Time DESC");
// or alternatively, if you don't know ahead of time that
// the query will be a SELECT...
//if (stmt.execute("SELECT foo FROM bar")) {
// rs = stmt.getResultSet();
//}
// Now do something with the ResultSet ....
messages.clear();
messages = new ArrayList<Message>();
while (rs.next()){
messages.add(new Message(rs.getString("ID"),
rs.getString("Author"),
rs.getString("Description"),
rs.getString("Time")));
}
}catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
} finally {
// it is a good idea to release
// resources in a finally{} block
// in reverse-order of their creation
// if they are no-longer needed
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) { // ignore }
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) { // ignore }
stmt = null;
}
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
// ignore -- as we can't do anything about it here
}
conn = null;
}
}
return this.messages;
}
//"添加留言" 按钮的action 属性方法
public String Button_onClick(){
if (userBar1.isUserlogin() == false) {
userBar1.setUrls( new ArrayList<URL>());
}
if (this.inputContent.length() < 5){
this.outputError = "留言字数太少不符合要求";
return null;
}
if(! this.inputURL.matches("http://.*")) {
this.outputError = "无效的网址";
return null;
}
boolean isAddMessageError = false;
Connection conn = null;
Statement stmt = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
isAddMessageError = true;
}
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/widebright?user=root&password=");
stmt = conn.createStatement();
this.inputContent.replaceAll("'", "");
this.inputAuthor.replaceAll("'", "");
this.inputURL.replaceAll("'","" );
String sqlText = "insert into widebright.message(Time,Description,Author,URL) values (now(),'"
+this.inputContent+"','" + this.inputAuthor+ "','" + this.inputURL+ "');" ;
System.out.println (sqlText);
isAddMessageError = stmt.execute( sqlText);
//if (stmt.execute("SELECT foo FROM bar")) {
// rs = stmt.getResultSet();
//}
}catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
isAddMessageError = true;
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) { // ignore }
stmt = null;
}
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
// ignore -- as we can't do anything about it here
}
conn = null;
}
if (isAddMessageError ){
this.outputError ="提交数据时,数据库发生错误!" ;
return null;
}
this.inputAuthor="";
this.inputContent="";
this.inputURL="";
return null;
}
public ArrayList<URL> getUrls() {
return urls;
}
public void setUrls(ArrayList<URL> urls) {
this.urls = urls;
}
public UIUserBar getUserBar1() {
return userBar1;
}
public void setUserBar1(UIUserBar userBar1) {
this.userBar1 = userBar1;
}
public javax.faces.component.UIInput getUsername() {
return username;
}
public void setUsername(javax.faces.component.UIInput username) {
this.username = username;
}
public void UserBar_Click(UserLeaveEvent e){
username.setValue("你点击了按钮了");
outputError= "你点击了按钮了";
}
}
faces-config.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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/javaeehttp://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<component>
<description>
用于在网页头显示用户登录链接的控件。</description>
<display-name>
UserBar</display-name>
<component-type>
UserBar</component-type>
<component-class>
widebright.UIUserBar</component-class>
</component>
<managed-bean>
<managed-bean-name>
tableExampleBean</managed-bean-name>
<managed-bean-class>
widebright.TableExampleBean</managed-bean-class>
<managed-bean-scope>
session</managed-bean-scope>
</managed-bean>
</faces-config>
最后运行效果如图:
上面的两行链接就是自定义控件的来的。
到此JSF学习结束,虽然还有很多东西可以学到 ,比如ajax4jsf控件,myfaces系列控件的使用啦等等。
但自己不是做这个东西,就等到有需要的时候在学吧。学jsf到初衷是比较一下jsf和.net的区别,然后熟悉一下java。 因为我以前是没用过java的。现在目的基本达到了吧,java用起来好像也不复杂很容易学到。jsf感觉还是没有.net用起来简单,微软就是好什么东西都白痴化了^_^ 。不过jsf这种开放源代码的方式很不错,学一学也可以加载自己对网页编程的理解吧。好像国内用jsf的人现在还不多,反正在互联网上能搜的到就很少了,不知道国外怎么样。
。。。widebright 。。。 学然后知不足.........
JSF 学习之 编写自定义控件(第二部分)
接上一篇文章自定义控件(custom tag)的使用
jsp页面代码:看到灰色背景部分代码了吗?
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://hi.baidu.com/widebright" prefix="widebright" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<f:view locale="zh">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="styles.css" rel="stylesheet" type="text/css" />
<title>"widebright的留言板"</title>
</head>
<widebright:userBar id="usrbar" urls=",新浪,1;"/>
<widebright:userBar id="test" urls="#{tableExampleBean.urls}" userlogin = "true" binding ="#{tableExampleBean.userBar1}" userleave="#{tableExampleBean.UserBar_Click}"/>
<body>
<h:form>
<div class="tit">添加留言:</div>
<table width="620" border="0" cellspacing="5" cellpadding="0">
<tr>
<td class="f14">姓 名:</td>
<td>
<h:inputText value="#{tableExampleBean.inputAuthor}" binding="#{tableExampleBean.username}" style="width:220px" maxlength="49" tabindex="1" required="true"> </h:inputText>
</td>
</tr>
<tr>
<td>网址或邮箱:</td>
<td><h:inputText value="#{tableExampleBean.inputURL}" style="width:360px" maxlength="128" tabindex="2"> </h:inputText>(选填)</td>
</tr>
<tr>
<td valign="top">内 容:</td>
<td><h:inputTextarea value="#{tableExampleBean.inputContent}"style="width:520px;height:155px" tabindex="3"> </h:inputTextarea>
</td>
</tr>
<tr>
<td valign="top"> </td>
<td valign="top">
<h:commandButton value="添加留言" action = "#{tableExampleBean.Button_onClick}"tabindex="5" id="btn_ok" type="submit"> </h:commandButton>
<h:outputText value= "#{tableExampleBean.outputError}" style="color: #FF0000"></h:outputText> </td>
</tr>
</table>
<div style = "width:100%;height:30px;background-color: #ddffdd;"> JSTL循环实现的表格,模仿百度空间留言板</div>
<div id = "Message">
<c:forEach var = "varMessage" items = "${tableExampleBean.messages}" varStatus="status">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="item">
<tr>
<td valign="top" class="index" width="5%"> ${varMessage.number}</td>
<td align="center" valign="top" width="10%">
<div class="user" style="overflow:hidden;">
<a href="http://hi.baidu.com/widebright" target='_blank' title=“http://hi.baidu.com/widebright”>
<img border="0" src="widebright.jpg"><br/>
${varMessage.user} </a>
</div>
</td>
<td class="cnt" style="padding-left:20px;">
<span class="date">${varMessage.time} </span>
<div class="desc" style="overflow:hidden;"> ${varMessage.description}</div>
</td>
</tr>
</table>
<div class="line"> </div>
</c:forEach>
</div>
<div style = "width:100%;height:30px;background-color: #ddffdd;"> JSF中h:dataTable 标签实现的表格</div>
<h:dataTable value="#{tableExampleBean.messages}" var="messageRow" border="1" rowClasses="ROW1,ROW2" headerClass="HEADING">
<h:column>
<f:facet name="header">
<f:verbatim>序号</f:verbatim>
</f:facet>
<h:outputText value="#{messageRow.number}"/>
</h:column>
<h:column>
<f:facet name="header">
<f:verbatim>作者</f:verbatim>
</f:facet>
<h:outputText value="#{messageRow.user}"/>
</h:column>
<h:column>
<f:facet name="header">
<f:verbatim>内容</f:verbatim>
</f:facet>
<h:outputText value="#{messageRow.time}"/>
<f:verbatim> <br> </f:verbatim>
<h:outputText value="#{messageRow.description}"/>
</h:column>
</h:dataTable>
</h:form>
</body>
</html>
</f:view>
页面后台代码:控件的banding属性很有意思的,注意到了吗?
package widebright;
import java.util.Collection;
import java.util.ArrayList;
import java.sql.*;
public class TableExampleBean {
// private Collection <Message> messages; //所有的留言
private Collection<Message> messages; // 所有的留言
//inputText输入框控件的值
private String inputAuthor;
private String inputURL;
private String inputContent;
private String outputError; //错误提示
private ArrayList<URL> urls = null;
private UIUserBar userBar1;
private javax.faces.component.UIInput username;
public TableExampleBean() {
messages = new ArrayList<Message>();
messages.add(new Message("0", "widebright", "好好学习,天天向上", "2007-11-5"));
messages.add(new Message("2", "widebright", "好好学习,天天向上", "2007-11-5"));
messages.add(new Message("3", "widebright", "好好学习,天天向上", "2007-11-5"));
urls = new ArrayList<URL>();
urls.add(new URL("http://www.163.com","网易", 1) );
urls.add(new URL("http://www.sina.com.cn","新浪", 2) );
}
public void setInputAuthor(String author){
this.inputAuthor = author;
}
public String getInputAuthor(){
return this.inputAuthor ;
}
public void setInputURL(String url){
this.inputURL= url;
}
public String getInputURL(){
return this.inputURL ;
}
public void setInputContent(String content){
this.inputContent= content;
}
public String getInputContent(){
return this.inputContent ;
4000
}
public void setOutputError(String error){
this.outputError= error;
}
public String getOutputError(){
return this.outputError ;
}
public void setMessages(Collection<Message> messages) {
this.messages = messages;
}
public Collection<Message> getMessages() {
Connection conn = null;
// assume that conn is an already created JDBC connection
Statement stmt = null;
ResultSet rs = null;
try {
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
return this.messages;
}
try {
// The JDBC URL format for MySQL Connector/J is as follows, with items in square brackets ([, ]) being optional:
// jdbc:mysql://[host][,failoverhost...][:port]/[database]
// [?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...
// If the hostname is not specified, it defaults to 127.0.0.1. If the port is not specified, it defaults to 3306, the default port number for
// MySQL servers.
// jdbc:mysql://[host:port],[host:port].../[database]
// [?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...
// If the database is not specified, the connection will be made with no default database
//The properties are listed in the following tables.
// user The user to connect as all versions
// password The password to use when connecting
//
conn = DriverManager.getConnection("jdbc:mysql://localhost/widebright?user=root&password=");
// Do something with the Connection
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT message.ID, Author,Time,Description ,URL FROM widebright.message order by Time DESC");
// or alternatively, if you don't know ahead of time that
// the query will be a SELECT...
//if (stmt.execute("SELECT foo FROM bar")) {
// rs = stmt.getResultSet();
//}
// Now do something with the ResultSet ....
messages.clear();
messages = new ArrayList<Message>();
while (rs.next()){
messages.add(new Message(rs.getString("ID"),
rs.getString("Author"),
rs.getString("Description"),
rs.getString("Time")));
}
}catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
} finally {
// it is a good idea to release
// resources in a finally{} block
// in reverse-order of their creation
// if they are no-longer needed
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) { // ignore }
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) { // ignore }
stmt = null;
}
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
// ignore -- as we can't do anything about it here
}
conn = null;
}
}
return this.messages;
}
//"添加留言" 按钮的action 属性方法
public String Button_onClick(){
if (userBar1.isUserlogin() == false) {
userBar1.setUrls( new ArrayList<URL>());
}
if (this.inputContent.length() < 5){
this.outputError = "留言字数太少不符合要求";
return null;
}
if(! this.inputURL.matches("http://.*")) {
this.outputError = "无效的网址";
return null;
}
boolean isAddMessageError = false;
Connection conn = null;
Statement stmt = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
isAddMessageError = true;
}
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/widebright?user=root&password=");
stmt = conn.createStatement();
this.inputContent.replaceAll("'", "");
this.inputAuthor.replaceAll("'", "");
this.inputURL.replaceAll("'","" );
String sqlText = "insert into widebright.message(Time,Description,Author,URL) values (now(),'"
+this.inputContent+"','" + this.inputAuthor+ "','" + this.inputURL+ "');" ;
System.out.println (sqlText);
isAddMessageError = stmt.execute( sqlText);
//if (stmt.execute("SELECT foo FROM bar")) {
// rs = stmt.getResultSet();
//}
}catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
isAddMessageError = true;
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) { // ignore }
stmt = null;
}
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
// ignore -- as we can't do anything about it here
}
conn = null;
}
if (isAddMessageError ){
this.outputError ="提交数据时,数据库发生错误!" ;
return null;
}
this.inputAuthor="";
this.inputContent="";
this.inputURL="";
return null;
}
public ArrayList<URL> getUrls() {
return urls;
}
public void setUrls(ArrayList<URL> urls) {
this.urls = urls;
}
public UIUserBar getUserBar1() {
return userBar1;
}
public void setUserBar1(UIUserBar userBar1) {
this.userBar1 = userBar1;
}
public javax.faces.component.UIInput getUsername() {
return username;
}
public void setUsername(javax.faces.component.UIInput username) {
this.username = username;
}
public void UserBar_Click(UserLeaveEvent e){
username.setValue("你点击了按钮了");
outputError= "你点击了按钮了";
}
}
faces-config.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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/javaeehttp://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<component>
<description>
用于在网页头显示用户登录链接的控件。</description>
<display-name>
UserBar</display-name>
<component-type>
UserBar</component-type>
<component-class>
widebright.UIUserBar</component-class>
</component>
<managed-bean>
<managed-bean-name>
tableExampleBean</managed-bean-name>
<managed-bean-class>
widebright.TableExampleBean</managed-bean-class>
<managed-bean-scope>
session</managed-bean-scope>
</managed-bean>
</faces-config>
最后运行效果如图:
上面的两行链接就是自定义控件的来的。
到此JSF学习结束,虽然还有很多东西可以学到 ,比如ajax4jsf控件,myfaces系列控件的使用啦等等。
但自己不是做这个东西,就等到有需要的时候在学吧。学jsf到初衷是比较一下jsf和.net的区别,然后熟悉一下java。 因为我以前是没用过java的。现在目的基本达到了吧,java用起来好像也不复杂很容易学到。jsf感觉还是没有.net用起来简单,微软就是好什么东西都白痴化了^_^ 。不过jsf这种开放源代码的方式很不错,学一学也可以加载自己对网页编程的理解吧。好像国内用jsf的人现在还不多,反正在互联网上能搜的到就很少了,不知道国外怎么样。
。。。widebright 。。。 学然后知不足.........
相关文章推荐
- JSF 学习之 编写自定义控件(第一部分)
- 第二部分:学习与知识发现 (任选一题)
- CI框架学习第二部分
- JSF2自定义组件编程系列 第二部分
- Linux 学习笔记 -- 第二部分 Linux 文件、目录与磁盘格式 -- 第8章 Linux 磁盘与文件系统管理
- Java基础学习笔记 第二部分 part 3
- JZ2440学习笔记,第二部分,移植uboot2015支持JZ2440的nor flash
- [学习《算法导论》]第二部分 排序和顺序统计量
- 一步一步学习sharepoint2010 workflow 系列第二部分:SharePoint无代码工作流 第6章 自定义Visio SharePoint 工作流(custome visio SharePoint workflow)
- 第二部分:学习与知识发现 (任选一题)
- (基于Java)编写编译器和解释器-第5章:解析表达式和赋值语句-第二部分(连载)
- Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第二部分(Page 7)
- Linux 学习笔记 -- 第二部分 Linux 文件、目录与磁盘格式 -- 第9章 文件与文件系统的压缩与打包
- 如何编写更好的SQL查询:终极指南-第二部分
- Django tutorial(2)【翻译】编写第一个Django app,第二部分——创建模型和使用模型
- 使用WSDL发布WebService(第二部分)简单对象访问协议——学习SOAP语法和使用SOAP发布WSDL
- 《编写可读性代码的艺术》读书笔记 第二部分 简化循环和逻辑
- Linux Unix shell 编程指南学习笔记(第二部分)
- 如何编写优雅(地道)的Python代码 - 第二部分
- Assembly学习心得(第二部分)