0

大家好,我被要求将旧的 Java EE Web 应用程序(JSP/Servlet、EJB、JPA)转换为现代 JSF 应用程序,除了 servlet 之外,我做得最多,

当前的servlet是:

@WebServlet(name = "StudentServlet", urlPatterns = {"/StudentServlet"})
public class StudentServlet extends HttpServlet {
    @EJB
    private StudentDaoLocal studentDao;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String action = request.getParameter("action");
        String studentIdStr = request.getParameter("studentId");
        int studentId=0;
        if(studentIdStr!=null && !studentIdStr.equals("")){
            studentId=Integer.parseInt(studentIdStr);    
        }
        String firstname = request.getParameter("firstname");
        String lastname = request.getParameter("lastname");
        String yearLevelStr = request.getParameter("yearLevel");
        int yearLevel=0;
        if(yearLevelStr!=null && !yearLevelStr.equals("")){
            yearLevel=Integer.parseInt(yearLevelStr);
        }
        Student student = new Student(studentId, firstname, lastname, yearLevel);

        if("Add".equalsIgnoreCase(action)){
            studentDao.addStudent(student);
        }else if("Edit".equalsIgnoreCase(action)){
            studentDao.editStudent(student);
        }else if("Delete".equalsIgnoreCase(action)){
            studentDao.deleteStudent(studentId);
        }else if("Search".equalsIgnoreCase(action)){
            student = studentDao.getStudent(studentId);
        }
        request.setAttribute("student", student);
        request.setAttribute("allStudents", studentDao.getAllStudents());
        request.getRequestDispatcher("studentinfo.jsp").forward(request, response);
    }

如何将其修改为 JSF bean?我需要添加和删除哪些部分

该应用程序是一个将学生详细信息添加到数据库的简单应用程序,它只是一些东西,所以我可以更多地了解数据库如何与 jsf 一起工作

谢谢

4

2 回答 2

5

如您所见,在您的 servlet 的服务方法中,所有内容都在一个地方搞砸了:获取请求参数、转换、验证、执行逻辑和执行数据库操作。在 JSF 中有特殊的组件来执行这些任务:

  • 请求参数 ( ) 的收集request.getParameter(...)由 Faces Servlet 透明地完成,因此您通常根本不需要弄乱它;
  • 通过将转换器类引入特定组件(@FacesConverter)或使用标准组件来完成转换;
  • 通过将一个或多个验证器附加到特定组件 ( @FacesValidator) 或使用标准组件来执行验证;
  • 执行逻辑是通过调用支持 bean 的方法完成的:根据组件/情况,您可以附加操作方法、操作侦听器方法、值更改侦听器方法或 ajax 侦听器方法。在您的情况下,您拥有返回导航案例结果 ( public void action(String action)) 的操作方法;
  • 执行数据库操作由注入的服务(通常由一个@EJB类)管理,就像在 servlet 中完成的那样。

接下来,JSF 提供了 UI 组件(like <h:inputText>)的集合,其状态绑定到模型,该模型又由@ManagedBean具有已知生命周期的支持 bean(like )表示。JSF 生命周期由六个阶段组成(这里不再赘述):

  • 恢复视图(从 HTTP 请求构建或恢复视图,包括 JSF 组件树);
  • 应用请求值(收集提交的请求参数,必要时转换它们的值并在本地以组件状态存储它们);
  • 过程验证(根据定义的规则集验证组件值);
  • 更新模型值(更新组件绑定的模型值);
  • 调用应用程序(调用方法,包括action/action listener/value change listener/ajax listener方法);
  • 渲染响应(渲染 HTML 并在 HTTP 响应中发送)。

所有这些阶段都可以链接到您的 servlet 处理的操作并进行分解。我现在想就您的经典 Servlet+JSP 组合的 JSF 对应物添加一些评论。

  1. String action = request.getParameter("action");等等

    在 JSF 中,您不需要做任何事情来收集这些参数,因为该作业由 Faces Servlet 透明地处理。

  2. studentId=Integer.parseInt(studentIdStr);等等

    在 JSF 中,转换(将请求参数作为字符串获取并将它们转换为其他 java 类)由 UI 组件的指定转换器处理。JSF 有一些内置转换器(如),但您可以通过实现接口DateTimeConverter来提供自己的转换器。Converter您可以通过指定converter属性 (like converter="myConverter")、嵌套<f:converter>标签 (<f:converter converterId="myConverter" />或嵌套标准标签 (like <f:convertDateTime ... />) 将其附加到给定组件。值得知道的是,某些值将自动为您强制转换。

  3. if(studentIdStr!=null && !studentIdStr.equals(""))等等

    这可能是您说明创建响应需要某些请求参数的方式。在 JSF 中,您通过指定requiredUI 组件的属性(如<h:inputText required="true" />)来做到这一点。

  4. if("Add".equalsIgnoreCase(action)){ doThis(); } else { doThat() }等等

    执行业务方法通常是在public String action()绑定到命令组件(如 )的操作方法(如 )中完成的<h:commandButton><h:commandButton action="#{yourBean.someAction}" />最常见的情况是,每个命令按钮都有一个业务操作。动作方法是 JSF 知道的托管 bean 中的方法,但是,您可以将具体动作传递给动作方法(如<h:commandButton action="#{yourBean.action('someAction)}" />with public String action(String action))。

  5. studentDao.addStudent(student)等等

    数据库操作在操作方法中以相同的方式处理:通过在注入的服务上调用必要的方法。

  6. Student student = new Student(studentId, firstname, lastname, yearLevel)等等

    您可以通过指定 UI 输入组件的值绑定来将提交的参数绑定到模型。因此,首先您预先准备一个模型,以便在您的支持 bean 中获得一个非空值Student student,然后将 JSF 组件绑定到模型值(如<h:inputText value="#{studentBean.student.studentId}" />)。这部分在没有人对这个问题的回答中得到了完美的解释。

  7. request.getRequestDispatcher("studentinfo.jsp").forward(request, response);等等

    操作方法可以返回一个字符串。此字符串是要转发到的导航案例结果(视图 ID)。所以,这本质上等价于public void action() { ... return "studentinfo"; }。此外,request.setAttribute("student", student)当 JSF 将 bean 与视图/请求/会话/应用程序相关联时,它也会透明地处理。当然,您也可以随意绑定您自己的其他对象。出于这个原因,JSF 在 EL 范围内公开了一些变量,并提供了对对象(视图/请求/会话/应用程序)的访问,以将您的参数与之关联。

于 2013-11-01T08:35:21.767 回答
3

这种转变并不容易。我假设您已经拥有“基础设施”,因为这对于一篇帖子来说显然太多了。基础设施是指所有必要的库、正确配置的 web.xml 等等。

以下内容与您的 servlet 并不完全相同,但它涵盖了基础知识,我将让您猜测如何进行编辑和搜索。

Student班级:

public class Student {
    private long studentId;
    private String firstName;
    private String lastName;
    // getters+setters
}

我们转换后的 servlet:

// this is how we make the bean known to JSF
@ManagedBean(name="studentBean")
@ViewScoped
public class StudentServlet implements Serializable {
    @EJB
    private StudentDaoLocal studentDao;

    // this object will be "automatically" filled with the values from our inputform on the xhtml page
    private Student student; // getter+setter

    // we have unique actions for everything... they are referenced from the xhtml page
    public String add() {
        // do your yearLevel logic here
        studentDao.addStudent(student);

        return "studentInfo.xhtml"; // forward to the next page
    }

    public String delete() {
        studentDao.deleteStudent(student.getStudentId());

        return "studentInfo.xhtml";
    }
}

我们需要一个用于 bean 的“GUI”的 xthml 页面,并将其命名为“student.xhtml”。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">

<h:head />
<h:body>

    <h:form>
        <h:inputText value="#{studentBean.student.studentId}" />
        <h:inputText value="#{studentBean.student.firstName}" />
        <h:inputText value="#{studentBean.student.lastName}" />
        <h:commandButton value="Add" action="#{studentBean.add()}" />
        <h:commandButton value="Delete" action="#{studentBean.delete()}" />
    </h:form>

</h:body>
</html>
于 2013-11-01T07:10:27.627 回答