www.91084.com

GVKun编程网logo

jsp:useBean范围(jsp中usebean)

2

最近很多小伙伴都在问jsp:useBean范围和jsp中usebean这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展设置:scope="application"制作网页历史访问量

最近很多小伙伴都在问jsp:useBean范围jsp中usebean这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展 设置:scope="application" 制作网页历史访问量...、 与 < jsp:getProperty>、@Scope(“ prototype”)bean范围未创建新bean、Bean的Spring会话作用域如何工作?Web上下文中Bean的默认范围是什么?等相关知识,下面开始了哦!

本文目录一览:

jsp:useBean范围(jsp中usebean)

jsp:useBean范围(jsp中usebean)

JSP代码是:

<jsp:useBean id="person"scope="session"></jsp:useBean><br> Name : <jsp:getProperty property="name" name="person"/><br> Surname : <jsp:getProperty property="surname" name="person"/>

尽管我在将请求转发到此Servlet的控制器Servlet
request作用域中而不是在session作用域中设置了java对象。<jsp:useBean>尽管标记中提到的作用域是会话,如何获取请求属性?如果它用于pageContext.findAttribute()获取属性,那么在该<jsp:useBean>标签中具有scope属性有什么用?

答案1

小编典典

PageContext#findAttribute()分别在页,请求,会话和应用范围,直到第一非扫描null属性值被发现,对于给定的属性键。另请参阅javadoc:

在页面,请求,会话(如果有效)和应用程序范围内 按顺序 搜索命名属性,并返回关联的值或null。

这就解释了为什么它在转发servlet中找到范围为1的请求,而不是在JSP中声明范围为1的会话。我们的EL
Wiki页面也对此进行了说明。

无论如何,如果您使用的是servlet,则不应<jsp:useBean>在应该由servlet管理的模型对象上使用。将<jsp:useBean>分别遵循不同的MVC水平实际使用servlet作为控制器时,这只会导致混乱和维护的麻烦。在Servlets Wiki页面的“编码样式和建议”部分中也明确提到了这一点。

因此,除了所有这些<jsp:xxx>事情,您可以执行以下操作:

<br>Name: ${person.name}<br>Surname: ${person.surname}

您只需要添加JSTL <c:out>来防止潜在的XSS攻击漏洞,同时重新显示用户控制的数据(请注意,<jsp:getProperty>这样做不会!)

<br>Name: <c:out value="${person.name}" /><br>Surname: <c:out value="${person.surname}" />

<jsp:useBean> 设置:scope=

设置:scope="application" 制作网页历史访问量...

定义一个 java bean

package com.lyq;
public class CountTimes {
    private long times = 0;
    private static count = 0;
    private String auther = "Coffee_Guy" ;
    public long getTimes() {
        return ++times;    // 取的一次加一
    }
    public void setTimes(long times) {
        this.times = times;
    }
    public String getAuther() {
        return auther;
    }
    
    public long getCount() {
        return ++count ;
    }
 
    
}
 

页面设置
 

<%@ page language="java" contentType="text/html" pageEncoding="GBK"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title> 计数器 </title>
        <style type="text/css">
            *{font-size: 12px;}
        </style>
    </head>
    <body align="center">
    
        <jsp:useBean id=" times"   scope = "application" />
            
        <h1>
        <font>
        作者:           <jsp:getProperty name=" times" property="auther" />
        该网页访问次量:<jsp:getProperty name=" times" property="times" />
         该网页访问次量 2:<jsp:getProperty name="times" property="count" />
        </font>
        </h1> 
    </body>
</html>

 

思考:

第一点:

经过简单验证有以下发现:
〈jsp:useBean〉标签 创建了一个 bean 实例 该实例是全局实例,是整个 web 应用中唯一的(id 是唯一的,在其它页面是直接引用的同一个。 )
例如:
 page1.jsp 页面有      <jsp:useBean id="times" class="com.lyq.CountTimes" scope="application"/>
那么在 page2.jsp 页面的 :       <jsp:useBean id="times" class="com.lyq.CountTimes" scope="application"/>
其实使用的都是一个 java bean 。
它的 scope 的范围是指该 bean 生命周期
第二点:
在定义 java bean 的类中引用了一个 静态变量 :count  在 java 中静态变量是唯一值,随着 java 类加载时初始化,知道该类被 GC 回收了才死亡。。这个和我们使用 java bean 的 application 范围做的访问量记录很相像。。。
大胆尝试一下,添加了如上黄色部分作测试。。。发现正是如猜测一样的。。
 

补充:

读者朋友如有发现不对,或有异议的欢迎留言一起探讨 共同学习。

 
 
 
 
 
 

<jsp:useBean>、<jsp:setProperty > 与 < jsp:getProperty>

与 < jsp:getProperty>

<jsp:useBean> 标签

  会调用 java 对象的无参构造方法,来创建实例。

   <jsp:useBean> 标签是用来搭配 JavaBean 元件的标准标签,这里指的 JavaBean 是满足以下条件的 Java 对象:
     1、必须实现 java.io.Serializable 接口
     2、具有无参数的构造器
     3、没有公开(public)的类变量
     4、具有公开的设值方法(Setter)与取值方法(Getter)
   但是在实际的测试中没有实现序列化接口也没有问题。

Demo:

package com.test;

public class AddServiceImpl {
    public String add() {
        return "1 + 2 = 5";
    }
}
Java Code
<%@page contentType="text/html" pageEncoding="UTF-8" %>
<jsp:useBean id="addService" class="com.test.AddServiceImpl"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
<p><%= addService.add()%></p>
</body>
</html>
index.jsp

测试地址:http://127.0.0.1/index.jsp

运行结果:1 + 2 = 5

查看转译后的 servlet 源码有如下内容:

com.test.AddServiceImpl addService = null;
      addService = (com.test.AddServiceImpl) _jspx_page_context.getAttribute("addService", javax.servlet.jsp.PageContext.PAGE_SCOPE);
      if (addService == null){
        addService = new com.test.AddServiceImpl();
        _jspx_page_context.setAttribute("addService", addService, javax.servlet.jsp.PageContext.PAGE_SCOPE);
      }
 
      out.print( addService.add());
index_jsp.java

源码分析

  使用 <jsp:useBean id="addService"/> 声明一个 java 对象后,servlet 会去 pageContext 域里根据指定的 id 值去寻找这个 java 对象,如果找不到,使用无参的构造方法创建并且再把它设置到 pageContext 作用域里。
  接着就可以使用设定的 id 值或者说 pageContext 域的 key——addService 来直接使用这个对象。

  使用 <jsp:useBean> 时,还可以指定 scope 属性,可以指定的值有 page(默认)、request、session 与 application。这样就先会到指定属性范围中寻找该实例,如果找到就直接使用;找不到也不会到其它作用域里去找,而是创建一个新对象并放入到指定的指定的作用域里。

  使用 <jsp:useBean> 时,还可以指定 type 属性。type 属性的设置可以是一个抽象类,也可以是一个接口。如果只设置 type 而没有设置 class 属性,则必须确定在某个属性范围中已经存在所要的对象,否则会发生 InstantiationException 异常。比如:

<jsp:useBean id="user" type="com.test.UserBase" class="com.test.User" scope="session"/>
View Code

这样产生的 Servlet 中,將會有以下的片段:

com.test.UserBase user = null;
      synchronized (session) {
        user = (com.test.UserBase) _jspx_page_context.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
        if (user == null){
          user = new com.test.User();
          _jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
        }
    }
View Code

 <jsp:setProperty> 标签

  会调用 java 对象 public 的 setter 方法。

  1、获取客户端参数

Demo

package com.test;

public class User {

    private String name;

    private String age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
}
Java Code
<%@page contentType="text/html" pageEncoding="UTF-8" %>
<jsp:useBean id="user" class="com.test.User"/>
<jsp:setProperty name="user"  param="name" property="name"></jsp:setProperty>
<jsp:setProperty name="user"  param="age" property="age"></jsp:setProperty>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
<p>
    姓名:<jsp:getProperty name="user" property="name"/><br>
    年龄:<jsp:getProperty name="user" property="age"/>
</p>
</body>
</html>
index.jsp

测试地址:http://127.0.0.1/index.jsp?name=zs&age=18

响应结果:

姓名:zs
年龄:18

如果是获取客户端参数,有三种写法:

写法一:
  <jsp:setProperty name="user" param="name" property="name"></jsp:setProperty>
  <jsp:setProperty name="user" param="age" property="age"></jsp:setProperty>

写法二:
  <jsp:setProperty name="user" property="name"></jsp:setProperty>
  <jsp:setProperty name="user" property="age"></jsp:setProperty>
  如果不指定请求参数名称,JSP 的自省机制会判断是否有相同名称的请求参数,有的话就找出并调用对应的 setter 方法。

写法三:
  <jsp:setProperty name="user" property="*"></jsp:setProperty>
  在 property 属性设置为 “*” 时,表示将自动寻找请求参数,如果请求参数名称为 xxx,就将请求参数值使用 setXxx () 方法。

  自省机制可以自动转换请求参数字符串为对应属性的基本类型。

  2、直接赋值

  比如:<jsp:setProperty name="user" property="password" value="123456"/>

  3、<jsp:setProperty> 的 name 属性说明

  在产生的 Servlet 代码中,会使用 PageContext 的 findAttribute (),依次从 page、request、session、application 中查找看看有无 name 指定的属性名称,找到的话,再通过反射机制找出 JavaBean 上的 setXxx () 方法并执行。


<jsp:getProperty> 标签

  <jsp:getProperty> 基本上就只有一种用法:<jsp:getProperty name="user" property="name"/>。
  这会通过 PageContext 的 findAttribute () 从 page、request、session、application 中依序查找 user 属性,并通过 getName () 方法取得值。


两种不两只的写法

一、在使用 <jsp:useBean> 时可以一并设置属性值

<jsp:useBean id="user" class="com.test.User" scope="session">
    <jsp:setProperty name="user" property="*" />
</jsp:useBean>
View Code

这样转译后产生以下代码:  

synchronized (session) {
        user = (com.test.User) _jspx_page_context.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
        if (user == null){
          user = new com.test.User();
          _jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
          org.apache.jasper.runtime.JspRuntimeLibrary.introspect(_jspx_page_context.findAttribute("user"), request);
        }
    }

二、分别编写

<jsp:useBean id="user" class="com.test.User" scope="session"/>
<jsp:setProperty name="user" property="*" />
View Code

这样转译后产生以下代码:

synchronized (session) {
        user = (com.test.User) _jspx_page_context.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
        if (user == null){
          user = new com.test.User();
          _jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
        }
      }
    org.apache.jasper.runtime.JspRuntimeLibrary.introspect(_jspx_page_context.findAttribute("user"), request);

如果使用后一种写法,则无论找到还是新建 JavaBean 对象,都一定会使用内省机制来设值。

@Scope(“ prototype”)bean范围未创建新bean

@Scope(“ prototype”)bean范围未创建新bean

我想在控制器中使用带注释的原型bean。但是春天正在创建一个单例豆。这是该代码:

@Component@Scope("prototype")public class LoginAction {  private int counter;  public LoginAction(){    System.out.println(" counter is:" + counter);  }  public String getStr() {    return " counter is:"+(++counter);  }}

控制器代码:

@Controllerpublic class HomeController {    @Autowired    private LoginAction loginAction;    @RequestMapping(value="/view", method=RequestMethod.GET)    public ModelAndView display(HttpServletRequest req){        ModelAndView mav = new ModelAndView("home");        mav.addObject("loginAction", loginAction);        return mav;    }    public void setLoginAction(LoginAction loginAction) {        this.loginAction = loginAction;    }    public LoginAction getLoginAction() {        return loginAction;    }    }

速度模板:

 LoginAction counter: ${loginAction.str}

Spring config.xml已启用组件扫描:

    <context:annotation-config />    <context:component-scan base-package="com.springheat" />    <mvc:annotation-driven />

每次我都会增加计数。无法弄清楚我要去哪里错了!

更新资料

正如@gkamal所建议的那样,我使-awareHomeController webApplicationContext可以解决问题。

更新的代码:

@Controllerpublic class HomeController {    @Autowired    private WebApplicationContext context;    @RequestMapping(value="/view", method=RequestMethod.GET)    public ModelAndView display(HttpServletRequest req){        ModelAndView mav = new ModelAndView("home");        mav.addObject("loginAction", getLoginAction());        return mav;    }    public LoginAction getLoginAction() {        return (LoginAction) context.getBean("loginAction");    }}

答案1

小编典典

范围原型意味着每次你向spring(getBean或依赖项注入)请求实例时,它将创建一个新实例并提供对该实例的引用。

在你的示例中,将创建LoginAction的新实例并将其注入到HomeController中。如果你有另一个将LoginAction注入到其中的控制器,你将获得一个不同的实例。

如果你希望每次调用都使用不同的实例-那么你每次都需要调用getBean-向单例bean中注入将无法实现这一点。

Bean的Spring会话作用域如何工作?Web上下文中Bean的默认范围是什么?

Bean的Spring会话作用域如何工作?Web上下文中Bean的默认范围是什么?

我正在研究Spring MVC,但有以下疑问:

  1. 会话范围的目的到底是什么?

阅读文档,我知道这将bean定义的范围限定为HTTP会话。仅在可感知网络的Spring
ApplicationContext上下文中有效。而且,每个用户会话一次创建一个新实例。

但是什么时候才使用呢?出于什么目的?你能举一个实际的例子吗?

  1. 在Spring MVC中,Web上下文的默认范围是什么?

我知道在Spring中,bean的默认范围是 单例, 但是在Web上下文中,bean的范围如何?

关于jsp:useBean范围jsp中usebean的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于 设置:scope="application" 制作网页历史访问量...、 与 < jsp:getProperty>、@Scope(“ prototype”)bean范围未创建新bean、Bean的Spring会话作用域如何工作?Web上下文中Bean的默认范围是什么?等相关内容,可以在本站寻找。

本文标签: