public enum Sex {   
    Male{   
        @Override  
        public String getTitle() {   
            return "男";   
        }   
    } ,   
    Female{   
        @Override  
        public String getTitle() {   
            return "女";   
        }   
    };   
    public abstract String getTitle();       @Override
    public String toString() {
return this.getTitle();
    } 
}  
对象Student 有个属性是 Sex sexjsp里面<s:iterator value="student">
<td>${sex}&nbsp;</td>
</s:iterator>这样输出的是Male
而<s:iterator value="student">
<td><s:property value="sex" />&nbsp;</td>
</s:iterator>则输出的是“男”
请问:
用el和struts tag的区别在哪里?
如何能用el直接重载toString方法输出中文?(注:输出${sex.title},这样不算)

解决方案 »

  1.   

    好像${sex}实际上取的是getSex()这样的public方法;
    struct2有待商榷...还有,怎么是在枚举中...
      

  2.   

    JSTL,EL在Struts2 里面最好不要使用,他们兼容不好,除非你有JSTL的那些过期的标签。
      

  3.   

    <s:iterator value="student"> <td>${sex}&nbsp;</td> </s:iterator>
    这种情况下是不会有输出的,sex并不直接存在于page,request,session,applicationp这4个作用域中,
    怎么会输出Male?
    <s:iterator value="student"> <td><s:property value="sex" />&nbsp;</td> </s:iterator>
    这种情况下确实输出的是“男”,
    因为这时候sex的值是从student对象中取得的lz会不会看错了?
      

  4.   

    <s:iterator value="student">
    从这段代码可以看出
    student是action的某个集合类属性,
    当请求转到jsp页面时,这个student的值是放在
    request对象中的一个名为"struts.valueStack"的com.opensymphony.xwork2.util.ValueStack对象中的,
    也可以这样获得student的值<%@ page import="com.opensymphony.xwork2.util.*" %><%
      ValueStack valueStack = (ValueStack)request.getAttribute("struts.valueStack");
      Object obj = valueStack.findValue("student");  // 返回student集合类对象
    %>这个值并不在那4个作用域中,
    所以我认为
    在<s:iterator value="student">标签中
    用${sex}是得不到Sex枚举的值的
      

  5.   


    struts2有默认的类型转换,是能得到的.
      

  6.   


    我发现有些人就喜欢睁着眼说瞎话,明明自己试一下就可以出结果的,非得瞎说请你把obj打印出来看看是什么东西!!!
    请你试过再说话!
      

  7.   


    那是你笨到没有在action里写上List student
    既然你试了,把你的代码贴出来啊,让大家膜拜一下呀...
      

  8.   


    public class StudentAction {

    @Autowired
    protected IStudentService studentService;

    private List student;

    public String execute() throws Exception {
    return list();
    }

    public String list() throws Exception {
    student = studentService.findAll();
    return "list";
    } public List getStudent() {
    return student;
    } public void setStudent(List student) {
    this.student = student;
    }
    }
    这是我的action,你的呢?
      

  9.   

    看看你的代码,有没有
    其他地方给这个"sex"赋过值,
    ${sex}这种写法,系统会在所有作用域寻找这个值,
    就算有输出,也不一定是从那个枚举中找到的
      

  10.   

    <s:iterator value="student">
    <td>${sex}&nbsp;</td>
    </s:iterator>
    这样的代码我也觉得不可能输出,因为没有定义过sex变量
    即使是枚举类型,因为重载了toString方法,
    所以就算这里会调用student.getSex()方法,
    那也会继续调用student.getSex().toString()方法
    所以不可能会出现Male的,出现Male的原因,除非你没用重载toString方法
    还有就是在别的地方定义了${sex}变量
    <s:iterator value="student">
    <td><s:property value="sex" />&nbsp;</td>
    </s:iterator>
    这样的代码是调用student.getSex().toString()方法
      

  11.   

    首先我认为Male这个值是不应该出来的。
    其次,说一下el和tag的区别。
    el:${obj}其实是调用了obj.toString()方法。
    tag:<s:iterator value="student"> 
        <td> <s:property value="sex" />&nbsp; </td> 
        </s:iterator> 
    这个其实是调用student对象.getSex()方法,得到的就就是getSex()的返回值,如果lz真的得到的是Male值,那么我请lz把student对象中的sex属性名字改成mySex,相应的enum类型改成mySex.这样一定不会有Male值,也就是说lz得到的Male有可能是特殊字段的默认值。
      

  12.   

    楼上的两位,我把student对象中的sex属性名字改成mySex,${sex}一样还是Male
    你们可以试一下MySex.java:public enum MySex { Male {
    @Override
    public String getTitle() {
    return "男";
    }
    },
    Female {
    @Override
    public String getTitle() {
    return "女";
    }
    };


    public abstract String getTitle(); @Override
    public String toString() {
    return this.getTitle();
    }}
    Student.javapublic class Student {

    private int id;

    private String name;

    private MySex mySex; public int getId() {
    return id;
    } public void setId(int id) {
    this.id = id;
    } public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public MySex getMySex() {
    return mySex;
    } public void setMySex(MySex mySex) {
    this.mySex = mySex;
    }
    }
    StudentAction.javapublic class StudentAction {

    private Student student;

    public String execute() throws Exception {
    System.out.println("StudentAction.execute()");
    student = new Student();
    student.setId(1);
    student.setName("aaa");
    student.setMySex(MySex.Male);
    return "success";
    }

    public Student getStudent() {
    return student;
    }

    public void setStudent(Student student) {
    this.student = student;
    }
    }
    student.jsp<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ taglib prefix="s" uri="/struts-tags" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>    
        <title>My JSP 'Student.jsp' starting page</title>
      </head>
      <body>
       <table>
        <s:iterator value="student">
       <tr>
       <td><input type="checkbox" name="radioGroup" value="${id}" /></td>
       <td>${name}&nbsp;</td>
       <td>${mySex}&nbsp;</td>
       <td><s:property value="mySex" /></td>
       <td>
       <a href="#" onclick="edit(${id})">编辑</a> 
       </td>
       </tr>
       </s:iterator>
       </table>
      </body>
    </html>
      

  13.   

    StudentAction.java public class StudentAction {

    private List student;

    public String execute() throws Exception {
    student = new ArrayList();
    Student stu1 = new Student();
    stu1.setId(1);
    stu1.setName("aaa");
    stu1.setMySex(MySex.Male);
    Student stu2 = new Student();
    stu2.setId(1);
    stu2.setName("bbb");
    stu2.setMySex(MySex.Female);
    student.add(stu1);
    student.add(stu2);
    return "success";
    } public List getStudent() {
    return student;
    } public void setStudent(List student) {
    this.student = student;
    }
    }
    还是一样,输出Male
      

  14.   

    楼主看看OGNL的知识吧.
    STRUTS2标签不支持EL,只能是OGNL
      

  15.   


    STRUTS2只是不支持struts tag与JSP EL表达式混用,并不是不支持el
    还是你去看看el和struts2的知识吧
      

  16.   

    lz的问题是"EL表达式和struts2 tag的区别",其实就因为用到了这两种标签访问同一个变量却得到了不同的结果。这个el和tag具体是访问的那个值需要源码的证明,这里本人没有看就不做评论了。但是从结果可以看出,el访问的是枚举类型的名字"Male",tag访问的是枚举类型的toString()方法。lz之前之所以看到了Male正是枚举类型的名字。
      

  17.   

    有空的时候再研究一下了
    ${mySex},这种没定义就使用的情况,我基本很少见
    如果是这样能访问的话,我觉得应该是el调用了enum.name()方法
    MySex.Male.name()返回的就是Male
    ${mySex}=Male,所以${mySex.name}就是Male了
      

  18.   


    那你认为应该怎么定义呢?那请问,我在顶楼提的问题如何解决?(如何写能在el的${mySex}里直接输出tostring方法)
      

  19.   

    建议不要用JSTL标签,既然使用的Struts2
    为什么不用Struts标签库?
      

  20.   


    我在顶楼上已经说了,struts2可以读出来,但是el读不出来,为什么?
    我要知道为什么?以及怎么解决。
    你这个遇到问题就绕路的方法不是好方法。
      

  21.   

    el表达式需要session存值
    而Struts 2.0 用的是它action中的get和set方法
      

  22.   

    测试了一下,分析如下:
    jstl对于普通的类的引用,比如${student},默认会调用toString方法
    而对于枚举类的支持不是很好,只能通过其get、set方法来获取结果,比如${mySex.title}返回就是“男”具体的可能要去看jstl标签的源码
      

  23.   


    谢谢你的回复,请问有没有什么好的解决方案呢?直接用${mySex}就可以输出“男”?
      

  24.   

    hava a try
    <s:iterator value="student" var="studentData">
    <c:set value="${studentData.mySex}" var="mySex"/>
    ${mySex}
    ...
      

  25.   

    如果还不行的话,用Converter吧
    可能是jstl对enum作了特殊处理
    因为重载toString方法的enum,不能通过enum.valueOf(enum.toString())还原,而enum.valueOf(enum.name())是可以还原的
      

  26.   

    EL表达式知道。struts1知道,2是不是不一样呢
      

  27.   

    public enum Sex {   
        Male{   
            @Override  
            public String toString() {   
                return "男";   
            }   
        } ,   
        Female{   
            @Override  
            public String toString() {   
                return "女";   
            }   
        };   
        public abstract String toString();       }  
    直接这样呢? LZ试试。
      

  28.   


    晕!   在我看来JSTL比Struts Tag 好用。  兼容不好就不知道是怎么得到的论!
      

  29.   

    我感觉还是JSTL好些,更加自由些
      

  30.   


    这跟我顶楼的代码不是一样吗?都是重载toString方法啊。这样是不行的。
      

  31.   

    up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up   up
      

  32.   

    最好去JAVAEYE讨论这个问题,那里有高人能给你解决,在这里高人少点
      

  33.   

    看看你的JSP版本,好像是2.0以上好像要在web.xml配置文件里面配置一下
      

  34.   


    说实话,这次我问的这个问题,让我对csdn很失望...
    看看上面的那些回答,搞笑的,捣乱的,睁着眼瞎说的
    自己不去实践一下就“我觉得”、“我认为”,自以为很权威,骗骗我就算了,但是误导别人就不对了
    真正能提出好一点的意见的倒没有几个......
      

  35.   

    <td><s:property value="sex" />&nbsp;</td>
    这个是匹配 getTitle()<td>${sex}&nbsp;</td> 是匹配  sex  属性
      

  36.   

    你把sex的类型改为List 再把male,famale,放进去,就可以遍历出来
      

  37.   

    去看一下EL的实现,你会发现用${}表达式去取enum类型的值的时候,它用的是enum.name()方法。而标签的输出的时候用的是enum的toString()方法。
      

  38.   

    不知道有什么值得讨论的.....去看编译成java后的jsp源文件,或看tag的源代码不就完了. 
    实践出真知,不是(掐)出来的.
      

  39.   


    恩,兄台说的太对了,不知兄台看过源码后能否解答我的问题呢?(如何用${mySex}里直接输出“男”,而不是Male)
      

  40.   

    哈,再送楼主一段代码,在EL当然,取回来指定变量的值后,会把它转换为String类型的值,然后处理方式如下:
            if (obj == null) {
                return "";
            } else if (obj instanceof String) {
                return (String) obj;
            } else if (obj instanceof Enum) {
                return ((Enum) obj).name();
            } else {
                return obj.toString();
            }
      

  41.   

    哈,至于91楼说的,看jsp编译结果的源代码,还真看不出东西来
      

  42.   


    请问这段代码写在哪里?action还是jsp里?
    action里难道我还要多循环一次转换?jsp里写这种代码你不觉得很丑陋?
      

  43.   

    无语了!这段代码不用你的,这是EL ${}的实现代码。你在页面是${var}人家调用的就是这段代码。