MVC模式中,常常需要各个部分之间交互信息,这就需要Bean。在展示层更是如此。所以就出现了useBean、EL等这些更方便,更优雅的解决方式。这里以hello world为例子,说明useBean的用法和优势。
不用useBean的例子:
web.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <servlet>
- <servlet-name>sayHello</servlet-name>
- <servlet-class>com.star7.goodjob.helloworld.SayHello</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>sayHello</servlet-name>
- <!-- 这里如果写成"/*"会出现什么情况呢?一大堆错误,为什么? -->
- <url-pattern>/say.jsp</url-pattern>
- </servlet-mapping>
- </web-app>
Word.java
- package com.star7.goodjob.helloworld;
- /**
- * 存储单词的内容,及属性。
- *
- * @created : 2011-5-26上午08:16:59
- * @author star7
- * @email : han_zc@126.com
- */
- public class Word {
- //单词的内容
- private String content;
- // 单词的颜色
- private String color;
- /**
- * @return the content
- */
- public String getContent() {
- return content;
- }
- /**
- * @param content the content to set
- */
- public void setContent(String content) {
- this.content = content;
- }
- /**
- * @return the color
- */
- public String getColor() {
- return color;
- }
- /**
- * @param color the color to set
- */
- public void setColor(String color) {
- this.color = color;
- }
- }
SayHello.java
- package com.star7.goodjob.helloworld;
- import java.io.IOException;
- import javax.servlet.RequestDispatcher;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- /**
- * 接受Http请求,向用户响应Word。
- *
- * @created : 2011-5-26上午08:21:50
- * @author star7
- * @email : han_zc@126.com
- */
- public class SayHello extends HttpServlet {
- /*
- * 响应用户的get请求。
- *
- * @see
- * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
- * , javax.servlet.http.HttpServletResponse)
- */
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- // 初始化Bean
- Word word = new Word();
- word.setContent("Hello Word!");
- word.setColor("red");
- // 将Bean放入请求属性中
- req.setAttribute("word", word);
- // 响应用户请求
- RequestDispatcher view = req.getRequestDispatcher("Show.jsp");
- view.forward(req, resp);
- }
- }
Show.jsp
- <%@ page language="java" contentType="text/html; charset=GB18030"
- pageEncoding="GB18030"%>
- <%@ page import="com.star7.goodjob.helloworld.Word" %>
- <html>
- <head>
- <title>good job</title>
- <%
- // 得到request中的属性
- Word word = (Word)request.getAttribute("word");
- %>
- </head>
- <body>
- <font color="<%=word.getColor() %>"><%=word.getContent() %></font><br>
- <%
- word.setColor("green");
- %>
- <font color="<%=word.getColor() %>"><%=word.getContent() %></font><br>
- </body>
- </html>
视图页面是用来显示信息的,而应该尽量避免使用不必要的逻辑,我不知道“使用脚本者,必死!”这句话到底有多严重。但避免java代码和html标记混合是必要的。
如果在<url-pattern>/say.jsp</url-pattern>改写成<url-pattern>/*</url-pattern>在语法上不会出错,而且这也是许多框架常用的伎俩。但在这里,由于使用RequestDispatcher从定向了,就会出现自己定向到自己,不断的追自己的尾巴。
如果改成useBean去处理Bean的操作,就会很轻松,代码也很美观了。
修改后的Show.jsp
- <%@ page language="java" contentType="text/html; charset=GB18030"
- pageEncoding="GB18030"%>
- <%@ page import="com.star7.goodjob.helloworld.Word" %>
- <html>
- <head>
- <title>good job</title>
- <jsp:useBean id="word" class="com.star7.goodjob.helloworld.Word" scope="request"></jsp:useBean>
- </head>
- <body>
- <font color='<jsp:getProperty property="color" name="word"/>'><jsp:getProperty property="content" name="word"/></font><br>
- <jsp:setProperty property="color" value="green" name="word"/>
- <font color='<jsp:getProperty property="color" name="word"/>'><jsp:getProperty property="content" name="word"/></font><br>
- </body>
- </html>
现在,是把精力集中在useBean的用法上来的时候了。
- <jsp:useBean id="bean的名称" class="bean的权限定类名" scope="page/request/session/context" />。这个标记首先会在是定的作用域中查找对象,如果存在,就直接拿来。如果不存在,就重新创建一个对象。这里面的scope是这个Bean的作用域。page表示只在本页面有效,request表示这个bean是request属性,session表示这个bean是session属性context是,这几个属性是servlet中的知识,稍后会解释。
- <jsp:setProperty name="bean的名称" property="属性名称" value="属性值" />就是向bean设置属性。当表单的名称和bean的属性名称相同时可以简写成这样:<jsp:setProperty name="bean的名称" property="*" />这会大大降低代码的编写量。
- <jsp:getProperty name="bean的名称" property="属性名称">这个标记是把bean的属性打印出来。
useBean的体
从上一节我们已经知道,useBean在找不到指定对象的时候重新创建对象。我们可能这样想--在没有找到对像的时候创建对象并设置属性。但是我们如果直接用<jsp:setProperty />时很可能覆盖掉本来存在的对象的属性。实例代码如下:
- <jsp:useBean id="people" class="com.star7.goodjob.People" scope="request" />
- <!-- 我们只想在从新创建对象的时候设置属性,而不像覆盖request作用域中的属性-->
- <jsp:setProperty name="people" property="name" value="default" />
使用useBean的体,进行有条件的设置属性。
实例代码如下:
- <jsp:useBean id="people" class="com.star7.goodjob.People" scope="request">
- <jsp:setProperty name="people" peoperty="name" value="default" />
- <jsp:useBean>
这样,只有创建新的bean是才会设置属性了。
useBean实现多态引用
<jsp:useBean id="people" class="非抽象类的权限定名" type="父类的权限定名" scope="作用域" />
这里面tyep实际上是用来声明的,而不会进行初始化。而class属性就可以声明并且初始化。所以,在作用域中有bean对象时<jsp:useBean id="people" type="com.star7.goodjob.People" scope="request" />是正确的,因为他不需要初始化。
作用域
page:是在本jsp文件中有效的bean。
request:是在一次请求中有效的bean。也就是request.setAttribute("beanName",bean实体)中的 bean实体。
session:是在一次会话中有效的bean。也就是session.setAttribute( "beanName",bean实体)中的 bean实体。
context:是整个应用中有效的bean。
浙公网安备 33010602011771号