TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
看了《 使用JSF 构建数据库驱动的应用程序》 一文后,动手做了练习。这是一个 订阅时事通讯的示例 Web 应用程序。订户通过提供他们的电子邮件地址、姓名和首选项进行注册。他们还必须选择一个口令, 以便以后可以更改他们的配置文件。 收获不少。
1、<!-- index.jsp --> <jsp:forward page="login.faces"/>
这个没有什么可说的。
2、 <!-- login.jsp -->登录页面
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/HTML" %> <c:remove var="subscriber" scope="session"/> <f:view> <f:loadBundle var="labels" basename="jsfdb.view.res.Labels"/>
<c:set var="stylesheet" value="/cwbwebhome/stylesheet.css"/> <html>
<head>
<title><h:outputText value="#{labels.login}"/></title>
<link rel="stylesheet" type="text/css" href="<c:out value=""/>">
</head>
<body> <h1><h:outputText value="#{labels.login}"/></h1> <h:outputLink value="subscribe.faces">
<h:outputText value="#{labels.subscribe}"/>
</h:outputLink> <h:form id="login"> <h:messages globalOnly="true" styleClass="message"/> <p><h:outputLabel for="email" value="#{labels.email}"/>
<h:message for="email" styleClass="message"/><br>
<h:inputText id="email" required="true" value="#{loginInfo.email}" size="40" maxlength="80">
<f:validateLength minimum="1" maximum="80"/>
</h:inputText> <p><h:outputLabel for="password" value="#{labels.password}"/>
<h:message for="password" styleClass="message"/><br>
<h:inputSecret id="password" required="true" value="#{loginInfo.password}" size="10" maxlength="20">
<f:validateLength minimum="6" maximum="20"/>
</h:inputSecret> <p><h:commandButton id="command" value="#{labels.login}" action="#{loginInfo.loginAction}"/> </h:form> </body>
</html> </f:view>
典型的jstl加jsf,看来要好好学习jsp2.0了,赶上不形势啊!
点击链接 Subscribe可进入subscribe.jsp(如图一),填订单页面。
命令按钮的"action"绑定到了视图loginInfo Bean的loginAction()方法, loginAction() 方法会根据登录用户的角色(订户或管理员)返回 profile 或 list(导航法则在faces-config.xml文件中定义) , 请求转向订户修改配置文件页面 profile.jsp(图二) 或订户列表页面 list.jsp(图三)。先看看LoginInfoBean.java源码:
- package jsfdb.view;
- import jsfdb.model.LoginInfo;
- import jsfdb.model.Subscriber;
- import jsfdb.model.ModelUtils;
- import jsfdb.model.err.LoginException;
- import jsfdb.model.err.IncorrectPasswordException;
- import jsfdb.model.err.UnknownSubscriberException;
- public class LoginInfoBean extends LoginInfo {
- public String loginAction() {
- //初始化一个SubscriberBean对象
- SubscriberBean subscriber= (SubscriberBean) ViewUtils.eval("#{subscriber}");
- //获取管理员的邮件地址,管理员的邮件在web.xml文件中配置
- String adminEmail= (String) ViewUtils.eval("#{initParam.adminEmail}");
- try {
- Subscriber selectedSubscriber
- = ModelUtils.getSubscriberDAO().select(this);//通过数据库验证口令与email
- ModelUtils.copy(selectedSubscriber, subscriber);//订户数据复制进视图bean
- subscriber.setLoggedIn(true);//登录标志设为true
- if (subscriber.getEmail().equals(adminEmail))
- return "list";//如果是超级管理员,转向list.jsp
- else
- return "profile";//如果是订户,转向profile.jsp
- } catch (LoginException x) {
- ViewUtils.addExceptionMessage(x);
- return null;
- } catch (UnknownSubscriberException x) {
- ViewUtils.addExceptionMessage(x);
- return null;
- } catch (IncorrectPasswordException x) {
- ViewUtils.addExceptionMessage(x);
- return null;
- }
- }
- }
复制代码

图一(填订单)
<!-- subscribe.jsp --> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> <f:view> <f:loadBundle var="labels" basename="jsfdb.view.res.Labels"/>
<c:set var="stylesheet" value="/cwbwebhome/stylesheet.css"/> <html>
<head>
<title><h:outputText value="#{labels.subscribe}"/></title>
<link rel="stylesheet" type="text/css" href="<c:out value=""/>">
</head>
<body> <h1><h:outputText value="#{labels.subscribe}"/></h1> <h:form id="subscribe"> <h:messages globalOnly="true" styleClass="message"/> <p><h:outputLabel for="email" value="#{labels.email}"/>
<h:message for="email" styleClass="message"/><br>
<h:inputText id="email" required="true" validator="#{subscriber.emailValidator}" value="#{subscriber.email}"
size="40" maxlength="80">
<f:validateLength minimum="1" maximum="80"/>
</h:inputText> <p><h:outputLabel for="password" value="#{labels.password}"/>
<h:message for="password" styleClass="message"/><br>
<h:inputSecret id="password" required="true" value="#{subscriber.password}" size="10" maxlength="20" redisplay="true">
<f:validateLength minimum="6" maximum="20"/>
</h:inputSecret>
<h:outputText value="#{labels.passwordDetail}"/> <p><h:outputLabel for="name" value="#{labels.name}"/>
<h:message for="name" styleClass="message"/><br>
<h:inputText id="name" required="true" value="#{subscriber.name}" size="40" maxlength="80">
<f:validateLength minimum="1" maximum="80"/>
</h:inputText> <p><h:outputText value="#{labels.newsletters}"/>
<h:message for="newsletters" styleClass="message"/><br>
<h:panelGrid id="newsletters" columns="3" border="0" cellspacing="5">
<h:panelGroup>
<h:selectBooleanCheckbox id="manager" value="#{subscriber.manager}"/>
<h:outputLabel for="manager" value="#{labels.manager}"/>
</h:panelGroup>
<h:panelGroup>
<h:selectBooleanCheckbox id="developer" value="#{subscriber.developer}"/>
<h:outputLabel for="developer" value="#{labels.developer}"/>
</h:panelGroup>
<h:panelGroup>
<h:selectBooleanCheckbox id="administrator" value="#{subscriber.administrator}"/>
<h:outputLabel for="administrator" value="#{labels.administrator}"/>
</h:panelGroup>
</h:panelGrid> <p><h:outputLabel for="subscriptionType" value="#{labels.subscriptionType}"/>
<h:message for="subscriptionType" styleClass="message"/><br>
<h:selectOneMenu id="subscriptionType" value="#{subscriber.subscriptionType}" required="true">
<f:validateLongRange minimum="1" maximum="3"/>
<f:selectItem itemLabel="#{labels.daily}" itemValue="#{subscriber.dailyConst}"/>
<f:selectItem itemLabel="#{labels.weekly}" itemValue="#{subscriber.weeklyConst}"/>
<f:selectItem itemLabel="#{labels.monthly}" itemValue="#{subscriber.monthlyConst}"/>
</h:selectOneMenu> <p><h:commandButton id="command" value="#{labels.subscribe}" action="#{subscriber.subscribeAction}"/> </h:form> </body>
</html> </f:view> 这是SubscriberBean.java源码
- package jsfdb.view;
- import jsfdb.model.Subscriber;
- import jsfdb.model.ModelUtils;
- import jsfdb.model.err.ProfileException;
- import jsfdb.model.err.SubscribeException;
- import jsfdb.model.err.UnsubscribeException;
- import javax.faces.component.UIComponent;
- import javax.faces.component.EditableValueHolder;
- import javax.faces.context.FacesContext;
- public class SubscriberBean extends Subscriber {
- public final static String INVALID_EMAIL_ID
- = "jsfdb.view.SubscriberBean.INVALID_EMAIL";
- public final static String SELECT_NEWSLETTER_ID
- = "jsfdb.view.SubscriberBean.SELECT_NEWSLETTER";
- private transient boolean loggedIn = false;
- public boolean isLoggedIn() {
- return loggedIn;
- }
- public void setLoggedIn(boolean loggedIn) {
- this.loggedIn = loggedIn;
- }
- public void emailValidator(FacesContext context, UIComponent comp, Object value) {
- String email = (String) value;
- if (email.indexOf("@") == -1) {
- String compId = comp.getClientId(context);
- ViewUtils.addErrorMessage(context, compId, INVALID_EMAIL_ID);
- ((EditableValueHolder) comp).setValid(false);
- }
- }
- public String subscribeAction() {
- if (countNewsletters() == 0) {
- ViewUtils.addErrorMessage(
- FacesContext.getCurrentInstance(),
- null, SELECT_NEWSLETTER_ID);
- return null;
- }
- try {
- ModelUtils.getSubscriberDAO().insert(this);
- setLoggedIn(true);
- return "subscribed";
- } catch (SubscribeException x) {
- ViewUtils.addExceptionMessage(x);
- return null;
- }
- }
- public String profileAction() {
- if (!loggedIn)
- return "login";
- if (countNewsletters() == 0) {
- ViewUtils.addErrorMessage(
- FacesContext.getCurrentInstance(),
- null, SELECT_NEWSLETTER_ID);
- return null;
- }
- try {
- ModelUtils.getSubscriberDAO().update(this);
- return null;
- } catch (ProfileException x) {
- ViewUtils.addExceptionMessage(x);
- return null;
- }
- }
- public String unsubscribeAction() {
- if (!loggedIn)
- return "login";
- try {
- ModelUtils.getSubscriberDAO().delete(this);
- return "unsubscribed";
- } catch (UnsubscribeException x) {
- ViewUtils.addExceptionMessage(x);
- return null;
- }
- }
- public String cancelAction() {
- if (!loggedIn)
- return "login";
- else
- return "cancel";
- }
- public int getDailyConst() {
- return TYPE_DAILY;
- }
- public int getWeeklyConst() {
- return TYPE_WEEKLY;
- }
- public int getMonthlyConst() {
- return TYPE_MONTHLY;
- }
- }
- 这是修改配置的页面:
复制代码
- [img]http://img.javaxxz.com/2014/10/10/025325046.jpg[/img]
- 图二
-
复制代码
再看看list.jsp
图三
<!-- list.jsp -->
<%@ page contentType="text/html; charset=gb2312" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> <c:if test="true">
<c:redirect url="/login.faces"/>
</c:if> <c:if test="false">
<c:redirect url="/profile.faces"/>
</c:if>
<sql:setDataSource driver="sun.jdbc.odbc.JdbcOdbcDriver" url="jdbc:odbc:jsfdb"/>
<sql:query var="subscriberList" scope="request">
SELECT * FROM subscribers ORDER BY subscriberEmail
</sql:query> <f:view> <f:loadBundle var="labels" basename="jsfdb.view.res.Labels"/>
<c:set var="stylesheet" value="/cwbwebhome/stylesheet.css"/> <html>
<head>
<title><h:outputText value="#{labels.list}"/></title>
<link rel="stylesheet" type="text/css" href="<c:out value=""/>">
</head>
<body> <h1><h:outputText value="#{labels.list}"/></h1> <h:outputLink value="profile.faces">
<h:outputText value="#{labels.profile}"/>
</h:outputLink> <h:outputLink value="logout.faces">
<h:outputText value="#{labels.logout}"/>
</h:outputLink> <h:form id="list"> <h:dataTable id="table" var="row" value="#{subscriberList}" border="1" cellpadding="5"> <h:column>
<f:facet name="header">
<h:outputText value="#{labels.email}"/>
</f:facet>
<h:outputText value="#{row.subscriberEmail}"/>
</h:column> <h:column>
<f:facet name="header">
<h:outputText value="#{labels.password}"/>
</f:facet>
<h:outputText value="#{row.subscriberPassword}"/>
</h:column> <h:column>
<f:facet name="header">
<h:outputText value="#{labels.name}"/>
</f:facet>
<h:outputText value="#{row.subscriberName}"/>
</h:column> <h:column>
<f:facet name="header">
<h:outputText value="#{labels.manager}"/>
</f:facet>
<h:outputText value="#{row.managerFlag}"/>
</h:column> <h:column>
<f:facet name="header">
<h:outputText value="#{labels.developer}"/>
</f:facet>
<h:outputText value="#{row.developerFlag}"/>
</h:column> <h:column>
<f:facet name="header">
<h:outputText value="#{labels.administrator}"/>
</f:facet>
<h:outputText value="#{row.administratorFlag}"/>
</h:column> <h:column>
<f:facet name="header">
<h:outputText value="#{labels.subscriptionType}"/>
</f:facet>
<h:outputText value="#{row.subscriptionType}"/>
</h:column> </h:dataTable> </h:form> </body>
</html> </f:view> 这个页面用jstl标记访问数据库! 数据适配层和数据访问对象DAO 这个应用通过ModelUtils类访问后端数据源, 提供了 SubscriberDAO 接口的两个实现,一个(JDBCSubscriberDAO.java)基于 JDBC API,另一个(TopLinkSubscriberDAO.java)使用 Oracle TopLink。下面是ModelUtils类的源码:- package jsfdb.model;
- import jsfdb.model.dao.SubscriberDAO;
- import java.beans.BeanInfo;
- import java.beans.Introspector;
- import java.beans.PropertyDescriptor;
- import java.beans.IntrospectionException;
- import java.lang.reflect.Method;
- import java.lang.reflect.InvocationTargetException;
- import java.util.ResourceBundle;
- import java.util.MissingResourceException;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- public class ModelUtils {
- public static final String RESOURCES
- = ModelUtils.class.getPackage().getName() + ".res.ModelResources";
- private static ResourceBundle resources;
- private static SubscriberDAO subscriberDAO;
- public static void log(Throwable x) {
- Logger.global.log(Level.SEVERE, x.getMessage(), x);
- }
- public static synchronized ResourceBundle getResources() {
- if (resources == null)
- try {
- resources = ResourceBundle.getBundle(RESOURCES);
- } catch (MissingResourceException x) {
- log(x);
- throw new InternalError(x.getMessage());
- }
- return resources;
- }
- public static String getResource(String key) {
- return getResources().getString(key);
- }
- public synchronized static SubscriberDAO getSubscriberDAO() {
- if (subscriberDAO == null)
- try {
- Class daoClass = Class.forName(getResource("DAO"));
- subscriberDAO
- = (SubscriberDAO) daoClass.newInstance();
- } catch (ClassNotFoundException x) {
- log(x);
- throw new InternalError(x.getMessage());
- } catch (IllegalAccessException x) {
- log(x);
- throw new InternalError(x.getMessage());
- } catch (InstantiationException x) {
- log(x);
- throw new InternalError(x.getMessage());
- }
- return subscriberDAO;
- }
- public static void copy(Object source, Object dest) {
- try {
- Class sourceClass = source.getClass();
- Class destClass = dest.getClass();
- BeanInfo info = Introspector.getBeanInfo(sourceClass);
- PropertyDescriptor props[]
- = info.getPropertyDescriptors();
- Object noParams[] = new Object[0];
- Object oneParam[] = new Object[1];
- for (int i = 0; i < props.length; i++) {
- Method getter = props[i].getReadMethod();
- if (getter == null)
- continue;
- Object value = getter.invoke(source, noParams);
- Method setter = props[i].getWriteMethod();
- if (setter != null && sourceClass != destClass)
- try {
- setter = destClass.getMethod(
- setter.getName(),
- setter.getParameterTypes());
- } catch (NoSuchMethodException x) {
- setter = null;
- }
- if (setter != null) {
- oneParam[0] = value;
- setter.invoke(dest, oneParam);
- }
- }
- } catch (IntrospectionException x) {
- log(x);
- throw new InternalError(x.getMessage());
- } catch (IllegalAccessException x) {
- log(x);
- throw new InternalError(x.getMessage());
- } catch (IllegalArgumentException x) {
- log(x);
- throw new InternalError(x.getMessage());
- } catch (SecurityException x) {
- log(x);
- throw new InternalError(x.getMessage());
- } catch (InvocationTargetException x) {
- log(x.getTargetException());
- throw new InternalError(
- x.getTargetException().getMessage());
- }
- }
- }
复制代码 此类的getSubscriberDAO()方法返回 SubscriberDAO 接口的一个实例,该接口定义了在关系数据库中选择、删除、插入、更新 Subscriber 对象的方法。 你的应用中具体使用哪一个后端数据源,在 ModelResources资源包有一个 DAO 参数,用于指定要使用的 DAO 实现. 这是ModelResources.properties文件:
DAO=jsfdb.model.dao.JDBCSubscriberDAO # DAO=jsfdb.model.dao.TopLinkSubscriberDAO
TopLinkSession=JSFDBSession JavaCompEnv=java:comp/env
DataSource=jdbc/OracleDS SelectStatement=SELECT
subscriberPassword,
subscriberName,
managerFlag,
developerFlag,
administratorFlag,
subscriptionType
FROM subscribers
WHERE subscriberEmail=? InsertStatement=INSERT INTO subscribers (
subscriberEmail,
subscriberPassword,
subscriberName,
managerFlag,
developerFlag,
administratorFlag,
subscriptionType )
VALUES (?, ?, ?, ?, ?, ?, ?) UpdateStatement=UPDATE subscribers SET
subscriberPassword=?,
subscriberName=?,
managerFlag=?,
developerFlag=?,
administratorFlag=?,
subscriptionType=?
WHERE subscriberEmail=? DeleteStatement=DELETE FROM subscribers
WHERE subscriberEmail=? SubscribeException=Subscription failed.
Please try another email address.
ProfileException=Couln"t update your profile.
Please contact the Webmaster.
UnsubscribeException=Unsubscription failed.
Please contact the Webmaster.
LoginException=Login failed.
Please contact the Webmaster.
UnknownSubscriberException=Unknown subscriber.
Please subscribe.
IncorrectPasswordException=Incorrect password.
Please try to login again.
我做这个例子时用了Access数据库- package jsfdb.model.dao;
- import jsfdb.model.LoginInfo;
- import jsfdb.model.Subscriber;
- import jsfdb.model.ModelUtils;
- import jsfdb.model.err.IncorrectPasswordException;
- import jsfdb.model.err.LoginException;
- import jsfdb.model.err.ProfileException;
- import jsfdb.model.err.SubscribeException;
- import jsfdb.model.err.UnknownSubscriberException;
- import jsfdb.model.err.UnsubscribeException;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- public class JDBCSubscriberDAO implements SubscriberDAO {
- // private DataSource dataSource;
- public JDBCSubscriberDAO() {
- Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
-
-
- }
- private void close(Connection conn, PreparedStatement ps)
- throws SQLException {
- if (ps != null)
- ps.close();
- if (conn != null)
- conn.close();
- }
- public Subscriber select(LoginInfo loginInfo)
- throws LoginException,
- UnknownSubscriberException,
- IncorrectPasswordException {
- Connection conn = DriverManager.getConnection("jdbc:odbc:jsfdb");
- PreparedStatement ps = null;
- try {
- conn = dataSource.getConnection();
- ps = conn.prepareStatement(
- ModelUtils.getResource("SelectStatement"));
- ps.setString(1, loginInfo.getEmail());
- ResultSet rs = ps.executeQuery();
- if (!rs.next())
- throw new UnknownSubscriberException();
- String password = rs.getString(1);
- if (!loginInfo.getPassword().equals(password))
- throw new IncorrectPasswordException();
- Subscriber subscriber = new Subscriber();
- subscriber.setEmail(loginInfo.getEmail());
- subscriber.setPassword(loginInfo.getPassword());
- subscriber.setName(rs.getString(2));
- subscriber.setManager(rs.getBoolean(3));
- subscriber.setDeveloper(rs.getBoolean(4));
- subscriber.setAdministrator(rs.getBoolean(5));
- subscriber.setSubscriptionType(rs.getInt(6));
- return subscriber;
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new LoginException();
- } finally {
- try {
- close(conn, ps);
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new LoginException();
- }
- }
- }
- public void insert(Subscriber subscriber)
- throws SubscribeException {
- Connection conn = DriverManager.getConnection("jdbc:odbc:jsfdb");
- PreparedStatement ps = null;
- try {
- conn = dataSource.getConnection();
- ps = conn.prepareStatement(
- ModelUtils.getResource("InsertStatement"));
- ps.setString(1, subscriber.getEmail());
- ps.setString(2, subscriber.getPassword());
- ps.setString(3, subscriber.getName());
- ps.setBoolean(4, subscriber.isManager());
- ps.setBoolean(5, subscriber.isDeveloper());
- ps.setBoolean(6, subscriber.isAdministrator());
- ps.setInt(7, subscriber.getSubscriptionType());
- int rowCount = ps.executeUpdate();
- if (rowCount != 1)
- throw new SubscribeException();
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new SubscribeException();
- } finally {
- try {
- close(conn, ps);
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new SubscribeException();
- }
- }
- }
- public void update(Subscriber subscriber)
- throws ProfileException {
- Connection conn = DriverManager.getConnection("jdbc:odbc:jsfdb");
- PreparedStatement ps = null;
- try {
- conn = dataSource.getConnection();
- ps = conn.prepareStatement(
- ModelUtils.getResource("UpdateStatement"));
- ps.setString(1, subscriber.getPassword());
- ps.setString(2, subscriber.getName());
- ps.setBoolean(3, subscriber.isManager());
- ps.setBoolean(4, subscriber.isDeveloper());
- ps.setBoolean(5, subscriber.isAdministrator());
- ps.setInt(6, subscriber.getSubscriptionType());
- ps.setString(7, subscriber.getEmail());
- int rowCount = ps.executeUpdate();
- if (rowCount != 1)
- throw new ProfileException();
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new ProfileException();
- } finally {
- try {
- close(conn, ps);
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new ProfileException();
- }
- }
- }
- public void delete(Subscriber subscriber)
- throws UnsubscribeException {
- Connection conn = DriverManager.getConnection("jdbc:odbc:jsfdb");
- PreparedStatement ps = null;
- try {
- conn = dataSource.getConnection();
- ps = conn.prepareStatement(
- ModelUtils.getResource("DeleteStatement"));
- ps.setString(1, subscriber.getEmail());
- int rowCount = ps.executeUpdate();
- if (rowCount != 1)
- throw new UnsubscribeException();
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new UnsubscribeException();
- } finally {
- try {
- close(conn, ps);
- } catch (SQLException x) {
- ModelUtils.log(x);
- throw new UnsubscribeException();
- }
- }
- }
- }
复制代码
源码下载:http://file.javaxxz.com/2014/10/10/025337937.zip |
|