通过反射获取表单中的值封装到JavaBean时,程序可以正常运转,但控制台报了一个异常
java.lang.NoSuchFieldException: iii
at java.lang.Class.getDeclaredField(Unknown Source)
原因是访问了一个不存在的属性iii.
后续做测试的时候 将button标签 多添加了一个name属性 iii, 果不其然自己编写的反射代码 会报异常。
<div id="maindiv">
<!-- 使用绝对路径表示action的值, / 是表示web浏览器中的绝对路径的根目录;在浏览器rul中表示从 "http://localhost:8090/" 开始 -->
<form class="form-horizontal" action="${pageContext.servletContext.contextPath}/LoginControl" method="post">
<div class="form-group">
<label class="col-sm-2 control-label">用户名:</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="userName" name="user_name" placeholder="登录用户名">
</div>
<label class="col-sm-2 control-label">密码:</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="userPsw" name="user_password" placeholder="密码">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-2">
<button type="submit" name="iii" class="btn btn-default">登录</button>
</div>
<div class="col-sm-offset-2 col-sm-2">
<button type="reset" class="btn btn-default">重置</button>
</div>
</div>
</form>
</div>
将button标签的 name属性去掉即可。 因为反射获取到的iii属性在 自己编写的JavaBean中找不到对应的属性。所以抛异常。
当然造成可能造成NoSuchFieldException异常原因有:
①没有对应字段;
②属性为私有时获取Field用的方法不是getDeclaredField。
下面记录以下自己编写的代码
UserInfo 的JavaBean
package com.mwb.bean;
public class UserInfo {
private Integer user_id;
private String user_name;
private String user_password;
public UserInfo() {
super();
// TODO Auto-generated constructor stub
}
public UserInfo(Integer user_id, String user_name, String user_password) {
super();
this.user_id = user_id;
this.user_name = user_name;
this.user_password = user_password;
}
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_password() {
return user_password;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
@Override
public String toString() {
return "userinfo [user_id=" + user_id + ", user_name=" + user_name + ", user_password=" + user_password + "]";
}
}
登录页面 index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录主页</title>
<!-- Bootstrap core CSS -->
<link href="static/plugins/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
<link href="static/plugins/bootstrap-3.3.7-dist/css/bootstrap-theme.min.css" rel="stylesheet">
<!-- Bootstrap core JavaScript-->
<!-- Placed at the end of the document so the pages load faster -->
<!--import jquery before bootstrap javascript-->
<script src="static/plugins/jquery-1.12.4/jquery-1.12.4.min.js"></script>
<script src="static/plugins/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<style>
#maindiv{
width: 80%;
padding-top: 10px;
}
</style>
</head>
<body>
<div id="maindiv">
<!-- 使用绝对路径表示action的值, / 是表示web浏览器中的绝对路径的根目录;在浏览器rul中表示从 "http://localhost:8090/" 开始 -->
<form class="form-horizontal" action="${pageContext.servletContext.contextPath}/LoginControl" method="post">
<div class="form-group">
<label class="col-sm-2 control-label">用户名:</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="userName" name="user_name" placeholder="登录用户名">
</div>
<label class="col-sm-2 control-label">密码:</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="userPsw" name="user_password" placeholder="密码">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-2">
<button type="submit" class="btn btn-default">登录</button>
</div>
<div class="col-sm-offset-2 col-sm-2">
<button type="reset" class="btn btn-default">重置</button>
</div>
</div>
</form>
</div>
</body>
</html>
三种方式 将从表单请求的数据封装到JavaBean中
方式1.硬编码 一个一个属性赋值
//方法一、从表单中提交的数据进行提取封装到userinfo JavaBean中 ( 硬编码 )
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String user_name = request.getParameter("user_name");
String user_password = request.getParameter("user_password");
UserInfo user = EasyFactory.getNewInstance(UserInfo.class);
user.setUser_name(user_name);
user.setUser_password(user_password);
//**************************************************************
方式2.通过反射方式 手动封装到JavaBean中
//方法二、利用反射的方式进行封装 自己手动编写反射
UserInfo user = EasyFactory.getNewInstance(UserInfo.class);
Enumeration<String> parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()) {
//System.out.println(parameterNames.nextElement());
String element = parameterNames.nextElement();
Field field;
try {
field = user.getClass().getDeclaredField(element);
field.setAccessible(true);
field.set(user,request.getParameter(element));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("JavaBean:" + user);
方式3.通过使用自己编写的工具类EasyFactory+ MyUtils+ BeanUtils的方式 封装到JavaBean中
//方法三、使用自己编写的MyUtils工具类 BeanUtils 进行封装到JavaBean中
UserInfo user = EasyFactory.getNewInstance(MyUtils.class).converRequestToBean(request, UserInfo.class);
EasyFactory.java( 获取一个类的实例对象 )
package com.mwb.utils;
public class EasyFactory {
public static <T> T getNewInstance(Class<T> clazz) {
T t = null;
try {
t = clazz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
}
MyUtils.java
package com.mwb.utils;
import java.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
public class MyUtils {
public <T> T converRequestToBean(HttpServletRequest request,Class<T> clazz) {
T t = null;
try {
t = clazz.newInstance();
if(request!=null) {
Enumeration<String> parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()) {
String tagName = parameterNames.nextElement();
String tagValue = request.getParameter(tagName);
//使用BeanUtils进行实体类的属性 反射设置
BeanUtils.setProperty(t, tagName, tagValue);
}
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
}