
先搞懂
和
的“搭档关系”
很多新手的第一个误区,是把当“独立工具”用——直接写标签就想赋值,完全忘了得先有个对象。我举个直白的例子:
就像你去超市买了个空的储物盒(创建
User
对象),是把零食、饮料放进盒子里(给对象属性赋值)。你连盒子都没有,直接往空气里塞东西,能塞进去才怪。
正确的步骤必须是“先创建对象,再赋值”,语法长这样:
<%-第一步:用useBean创建User对象,id是“user”(盒子的“名字”),存在request作用域 %>
<%-
第二步:用setProperty给user对象的属性“装东西” %>
<setproperty name="user" property="">
这里要记死两个“必须一致”:
的name
属性,必须和
的id
完全一样——比如id
是“user”,name
就不能是“users”(我之前犯过这个错,差一个s
,查了半小时日志才发现); public void setUsername(String username)
方法(首字母大写的规则别忘,比如属性是“userName”,set方法是“setUserName”,不是“setusername”)。小宇之前的问题就是第二个——他的Bean里把setUsername
写成了setusername
(全小写),结果找不到对应的方法,赋值失败。改完set方法的名字,立刻就好了——真的,计算机比你想象中更“较真”。
三种常用的
用法,覆盖你90%的场景
搞懂搭档关系后,接下来讲三种最常用的用法——不管你是做表单提交、设置默认值,还是手动调整参数,都能用得上。我会结合自己的项目经验,把“为什么要这么用”“踩过的坑”都给你说清楚。
property=""
(最省心,但要守规矩)这是我最常用的方法——处理表单提交时,用property=""
就能自动把表单里的参数“搬”到JavaBean里。比如你有个登录表单:
用户名:
密码:
然后在login.jsp
里写:
<setproperty name="user" property="">
这样表单里的“username”会自动对应User
类的setUsername
方法,“password”对应setPassword
方法——省得你写十个标签,效率翻倍。
但这个方法有个“死规矩”:表单里的input name
,必须和JavaBean的属性名(set方法)完全一致。比如表单里的name是“userName”,Bean里就得有setUserName(String userName)
方法,大小写都不能错。我之前做学生信息系统时,把表单里的“phone”写成了“Phone”(首字母大写),结果Bean里是setPhone
,赋值失败——后来把表单的name改成“phone”才解决,你说这事冤不冤?
有时候表单里的name和Bean的属性名不一样(比如旧项目遗留的代码,改表单比改Bean麻烦),比如表单里是“user_email”,但Bean里是“email”,这时候就不能用“”了,得手动“搭桥”。比如:
这里的property
是Bean里的属性名(对应setEmail
方法),param
是表单里的input name
(user_email)。这样就能把表单里的“user_email”值,精准赋给Bean的“email”属性——比改表单或改Bean代码省事多了。
我之前帮朋友改电商项目时,他的表单里用了“user_mobile”,但Bean里是“mobile”,用这个方法一调整,立刻就对上了——当时他拍着大腿说:“原来还能这么玩!”
如果需要给属性设置默认值(比如用户没填年龄,默认设为18),就用value
属性:
这个方法适合“不管用户填没填,都要给个基础值”的场景,比如注册时默认用户等级是“普通会员”,就可以写property="level" value="普通会员"
。
更灵活的是,value
里可以写EL表达式,比如:
意思是“如果表单里有age
值,就用表单的;没有就用18”。我之前做问卷调查系统时,用这个表达式处理“未填写”的情况,比写Java代码简洁多了——毕竟能少写一行代码,就少一分出错的可能。
为了让你更清楚这三种用法的区别,我做了个对比表:
用法类型 | 语法示例 | 适用场景 | 注意事项 |
---|---|---|---|
自动匹配表单 |
|
表单提交后批量赋值 | 表单name与Bean属性名(set方法)完全一致 |
手动指定单个属性 |
|
表单name与Bean属性名不一致 | property对应Bean属性,param对应表单name |
指定固定值 |
|
设置默认值或固定值 | value可填常量或EL表达式 |
新手最常踩的3个坑,我帮你“排雷”
讲完用法,再跟你唠唠我和身边人踩过的坑——这些错误看着简单,但90%的新手都会犯,我当初也是踩了一遍才记住。
坑1:
的scope
没“对齐”
的
scope
属性(比如request
、session
、page
、application
),决定了对象存在哪里。如果useBean
的scope
是session
,但你在另一个页面用时,没写
useBean
标签,肯定找不到对象。比如:
<%-错误示例:page2.jsp里没写useBean,直接用setProperty %>
<setproperty name="user" property=""> <%-报错:找不到user对象 %>
解决方法很简单:在要用的页面,先写
找到对象——不管
scope
是什么,只要id
一致,就能找到。比如page2.jsp
里应该写:
<%-找到session里的user %>
<setproperty name="user" property="">
我之前就是因为省了这行代码,查了半小时错——真的,别嫌麻烦,这行代码是“钥匙”。
坑2:JavaBean里没有set
方法(最容易忽略的错)
是通过调用Bean的
set
方法来赋值的——如果Bean里只有get
方法(比如getUsername
),没有set
方法(setUsername
),肯定赋值失败,报错“Cannot find any information on property ‘username’…”。
小宇当初的问题就是这个——他以为只要在Bean里定义private String username;
就行,完全忘了写set
方法。解决方法超简单:给每个要赋值的属性,写对应的set
方法(规则是“set
+属性名首字母大写”,比如属性是“age”,set
方法是“setAge
”)。
坑3:表单post
提交没处理中文乱码
这个不算本身的错,但会让你误以为是它的问题——比如表单用
post
提交,JSP页面没设置编码,结果username
是“张三”,赋值后变成“å¼ ä¸”(乱码)。
解决方法只要在JSP页面开头加一行:
记住,这行代码要放在所有获取参数的代码之前(比如、
request.getParameter()
)。我之前做博客系统时,就是因为漏了这行,以为是的问题,查了半天——说多了都是泪。
按这些方法调完,你再用${user.username}
输出看看,是不是有值了?我当初学的时候,就是按这个流程走的,从“赋值失败”到“一次成功”,也就花了十五分钟。对了,你之前有没有遇到过的奇怪问题?比如赋值后是
null
,或者报奇怪的错?欢迎在评论区告诉我——毕竟我也是从“踩坑”过来的,说不定能帮你省点时间。
我之前做表单提交的时候,遇到过好几次中文乱码的情况——明明表单里填的是“张三”,点提交后JavaBean里的用户名居然变成“å¼ ä¸”这种乱码,当时我还以为是的问题,翻来覆去查标签语法,结果完全没用。后来问了公司的老程序员才知道,根本不是标签的锅,是POST提交的编码没处理对。你想啊,POST提交的表单数据默认用的是ISO-8859-1编码,这种编码压根不认识中文,就像你拿英语字典查中文词,肯定翻不到正确意思,数据自然就乱成一团了。
解决方法其实超简单,就加一行代码的事——在JSP页面的最开头,所有获取参数的代码之前,写。这行代码相当于给数据“做了个翻译”,把POST过来的ISO-8859-1编码转换成UTF-8,这样赋值的时候,就能准确认出中文了。不过有个关键点得记死:这行代码必须放在所有跟获取参数有关的代码前面,比如创建对象、赋值,或者用request.getParameter()拿数据这些操作之前。我之前就犯过傻,把这行代码写在后面,结果还是乱码——因为其实已经在悄悄找对象了,这时候再改编码,早就来不及了。上次帮朋友改注册页面,就是因为顺序错了,折腾了半小时才弄好,现在想想都觉得自己当时怎么那么笨,这么简单的顺序问题都能搞错。
还有次更搞笑的,我帮一个刚学JSP的学弟调代码,他说“我加了那行代码啊,怎么还是乱码?”我一看他的页面,原来他把写成了——虽然“utf8”和“UTF-8”看着差不多,但计算机认死理,必须写全大写加横杠才行。你说这事冤不冤?就差个小细节,结果白折腾半天。所以啊,有时候不是方法不对,是你漏了点“抠细节”的心思。
对了,还有种情况要注意:如果你的JSP页面用了,别以为这行能代替request.setCharacterEncoding——这行是设置页面输出的编码,而request.setCharacterEncoding是设置请求数据的编码,两者管的是不同的事。我之前就混过一次,以为加了contentType就不用管请求编码了,结果还是乱码,后来查了W3C的文档才明白,这两个编码设置是分开的,一个管“输出给浏览器”,一个管“接收表单数据”,缺了哪个都不行。
必须和一起用吗?
是的,需要依赖创建的对象才能赋值。相当于“创建/找到”一个JavaBean对象(比如User),则是给这个对象的属性“装值”——没有对象(就像没有储物盒),自然无法“装东西”。所以使用前,必须先通过定义或找到对应的对象,且两者的id(对象名)和name(要赋值的对象名)必须完全一致。
表单里的input name和JavaBean属性名不一致,怎么用赋值?
可以用的param属性“搭桥”。比如表单里的input name是“user_email”,但JavaBean的属性是“email”(对应setEmail方法),可以写:——其中property是Bean里的属性名(对应set方法),param是表单里的input name,这样就能把表单值精准赋给Bean属性,不用修改表单或Bean的代码。
JavaBean里的set方法大小写错了,为什么赋值失败?
是通过调用JavaBean的set方法来赋值的,而set方法的命名必须严格遵循“set+属性名首字母大写”的规则(比如属性是“username”,set方法必须是setUsername;属性是“userName”,set方法是setUserName)。如果把setUsername写成setusername(全小写),找不到对应的方法,就会报错“Cannot find any information on property ‘username’…”,导致赋值失败。
的scope设为session,其他页面用为什么找不到对象?
的scope属性决定了对象的存储范围(比如session表示对象存在会话中)。如果在其他页面直接用,没有先通过“找到”这个对象,系统就会因为“找不到对象”报错。解决方法是:在需要用的页面,先写——通过id和scope找到session中的对象后,再用赋值。
用post提交表单,赋值后中文乱码怎么办?
这是因为post提交的表单数据默认编码不是UTF-8。解决方法是在JSP页面的最开头(所有获取参数的代码之前)添加:——这样就能把表单提交的中文数据转成UTF-8编码,避免赋值后出现乱码。注意这行代码必须放在、或request.getParameter()等获取参数的代码之前才有效。