自动赋值操作
所有的开发中,几乎都会将用户传递的数据转换为简单Java类的形式进行操作。
那么现在可以继续采用之前的方式进行操作,可是又一点比较麻烦;
在BeanOperate类里面的构造方法有两个;
怎么区分传递来的内容是使用数组接收还是使用单个字符串接收呢?
范例:定义一个页面index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'MyJsp.jsp' starting page</title>
</head>
<body>
<form action="dept/insert" method="post">
部门编号:<input type="text" name="dept.deptno" id="dept.deptno" value="10">
部门名称:<input type="text" name="dept.dname" id="dept.dname" value="开发部">
位置字段:<input type="checkboc" name="dept.loc" id="dept.loc" value="1">第1位置
<input type="checkboc" name="dept.loc" id="dept.loc" value="2">第2位置
<input type="checkboc" name="dept.loc" id="dept.loc" value="3">第3位置
<input type="checkboc" name="dept.loc" id="dept.loc" value="4">第4位置
<input type="checkboc" name="dept.loc" id="dept.loc" value="5">第5位置
<input type="checkboc" name="dept.loc" id="dept.loc" value="6">第6位置
公司名字:<input type="text" name="dept.company.title" id="dept.company.title" value="hello公司">
<input type="submit" value="提交">
<input type="reset" value="重置">
</body>
</html>
所有的Servlet都需要进行提交参数与简单Java类的转换。
现在可以假设只有带“.”才需要实现自动的转换操作。
范例:在doGet()方法里面进行存在
public abstract class DispatcherServlet extends HttpServlet{
private static final String PAGES_BASENAME="Pages";
private static final String MESSAGES_BASENAME="Messages";
private ResourceBundle pagesResource;
private ResourceBundle messagesResource;
protected HttpServletRequest request;
protected HttpServletResponse response;
public void init()throws ServletException{
this.pagesResource=ResourceBundle.getBundle(
PAGES_BASENAME,Locale.getDefault());
this.messagesResource=ResourceBundle.getBundle(
MESSAGES_BASENAME_BASENAME,Locale.getDefault());
}
/*
取得在Pages.properties文件里面定义的访问路径
key 访问路径的key
return 配置文件中的路径内容,如果没有返回null
*/
public String getPath(String key){
return this.pagesResource.getString(key);
}
/*
取得Messages.properties文件中的配置文字信息
key 访问文字信息的key
args 所有占位符的内容
return 配置文件中的内容,并且是组合后的结果,如果没有返回null
*/
public String getMsg(String key,String ...args){
String note=this.messagesResource.getString(key);
if(args.length>0||this.getTitle()==null){//传递了参数内容
return MessageFormat.format(note,args);
}else{
return MessageFormat.format(note,this.getTitle());
}
}
/*
交由不同的子类来实现,可以由子类来设置统一的占位符提示信息名称标记
return 返回不同子类的描述信息
*/
public abstract String getTitle();
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
this.request=request;
this.response=response;
String path=this.getPath("errors.page");
String status=request.getRequestURI().substring(
request.getRequestURI().lastIndexOf("/")+1);
//现在可以找到当前类对象this,以及要调用的方法名称status,可以利用反射进行调用
if(status!=null&&status.length()>0){
//取得全部的请求参数名称,之所以需要名称,主要是确定自动赋值的存在
Enumbertion<String> enu=request.getParameterNames();
while(enu.hasMoreElements()){ //循环所有的参数名称
String paramName=enu.nextElement();
if(paramName.contains(".")){//按照简单Java类处理
AttributeType at=new AttributeType(this,paramName);
if(at.getFieldType().contains("[]")){ //按照数组的方式进行处理
BeanOperate bo=new BeanOperate(this,
paramName,request.getParameterValues(paramName));
}else{//按照单个字符串的方式进行处理
BeanOperate bo=new BeanOperate(this,
paramName,request.getParameter(paramName));
}
}
}
try{ //只有将对应的数据准备完毕了,才可以执行以下方法
Method method=this.getClass().getMethod(status);
path=(String)method.invoke(this);//反射调用方法
}catch(Exception e){
e.printStackTrace();
}
}
request.getRequestDispatcher(path).forward(request,response);
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
this.doGet(request,response);
}
}
首先要取得所有的提交参数以及对应的内容。
但是现在对于提交参数会产生以下情况;
我们无法去区分出是使用request.getParameter()还是request.getParamerValues()接收参数,
这样就无法确定使用哪一个BeanOperate类的构造;
有些参数可能不需要进行简单Java类的处理。
但是现在的程序之中并没有解决那里使用getParameter()与getParameterValue()两个方法的操作。
唯一能做的区分只有一种形式,根据参数的名称挖掘数据类型,可以再定义一个专门的处理类,进行属性的处理。
AttributeType.java
public class AttributeType{
private Object currentObject; //当前的操作对象
private String attribute; //属性的字符串描述
private Field field; //属性的成员
public AttributeType(Object currentObject,String attribute){
this.currentObject=currentObject;
this.attribute =attribute;
this.handleParameter();
}
private void handleParameter(){针对于传入数据进行处理
try{
String result[]=this.attribute.split("\\.");
if(result.length==2){//现在表示的是单级操作
//对于类中的getter方法上是不存在参数的,所以参数类型为空
Method getMet=this.currentObject.getClass()
.getMethod("get"+StringUtils.initcap(result[0]));
this.currentObject=getMet.invoke(this.currentObject);//调用了getter方法
Field field=ret.getClass().getDeclareField(result[1]);//取得对象成员
}else{ //现在表示的多级操作
for(int x=0;x<result.length;x++){
//System.out.println("x="+x+"="this.currentObject);
//必须知道当前操作的成员对象,因为只要有对象存在才可以找到属性类型,才可以调用setter方法
this.field=this.currentObject.getClass().getDeclareField(result[x]);
//System.out.println(this.field.getName());
if(x<result.length-1){//现在不是最后一块组成,还有内容
Method met=this.currentObject.getClass()
.getMethod("get"+StringUtils.initcap(result[x]));
this.currentObject=met.invoke(this.currentObject);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
public Field getField(){
return this.field;
}
public String getFieldType(){
return this.field.getType().getSimpleName();
}
}
@SuppressWarnings("serial")
@WebServlet(urlPatterns="dept/*")
public class DeptServlet extends DispatcherServlet{
private Dept dept=new Dept();
public String insert(){
System.out.println("======DeptServlet--insert()==========");
return "";
}
public String update(){
System.out.println("======DeptServlet--update()==========");
return "";
}
public String getTitle(){
return "部门";
}
public Dept getDept(){
return dept;
}
//覆写dept略
}
public class Dept{
private String dname;
private Integer deptno;
private Integer loc[];
private Company company=new Company();//必须实例化
public void setDeptno(Integer deptno){
this.deptno=deptno;
}
public Integer getDeptno(){
return deptno;
}
public void setDname(String dname){
this.dname=dname;
}
public String getDname(){
return dname;
}
public Company getCompany(){
return company;
}
}
public class BeanOpreate{
private Object currentObj;//表示当前程序的保存对象
private String attribute;//要操作的属性
private String value;//要操作的内容
private String arrayValue[];//要操作的数组内容
private Field field;//表示要操作的成员对象
/*
进行操作数据的接收,接收后才可以进行数据的设置操作
obj表示当前要操作次功能的类对象
attribute包含了 "对象.属性.属性... " 字符串
value 表示属性内容
*/
public BeanOpreate(Object Obj,String attribute,String arrayValue[]){
this.currentObj=obj;//保存当前的操作对象
this.attribute=attribute;
this.arrayValue=arrayValue;
this.handleParameter();
this.setValue();
}
//进行数组数据的操作
public BeanOpreate(Object Obj,String attribute,String value[]){
this.currentObj=obj;//保存当前的操作对象
this.attribute=attribute;
this.value=value;
this.handleParameter();
this.setValue();
}
private void handleParameter(){针对于传入数据进行处理
try{
String result[]=this.attribute.split("\\.");
if(result.length==2){//现在表示的是单级操作
//对于类中的getter方法上是不存在参数的,所以参数类型为空
Method getMet=this.currentObj.getClass()
.getMethod("get"+StringUtils.initcap(result[0]));
this.currentObj=getMet.invoke(this.currentObj);//调用了getter方法
Field field=ret.getClass().getDeclareField(result[1]);//取得对象成员
}else{ //现在表示的多级操作
for(int x=0;x<result.length;x++){
//System.out.println("x="+x+"="this.currentObj);
//必须知道当前操作的成员对象,因为只要有对象存在才可以找到属性类型,才可以调用setter方法
this.field=this.currentObj.getClass().getDeclareField(result[x]);
//System.out.println(this.field.getName());
if(x<result.length-1){//现在不是最后一块组成,还有内容
Method met=this.currentObj.getClass()
.getMethod("get"+StringUtils.initcap(result[x]));
this.currentObj=met.invoke(this.currentObj);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
private void setValue(){ //定义一个专门设置属性内容的方法,调用的setter操作
try{
Method setMet=this.currentObj.getClass().getMethod("set"+StringUtils
.initcap(this.field.getName()),this.field.getType());
setMet.invoke(this.currentObj,this.value);
String type=this.field.getType().getSimpleName();//取得数据类型
if("int".equalsIgnoreCase(type)||"integer".equalsIgnoreCase(type)){
if(this.value.matches("\\d+")){
setMet.invoke(this.currentObj,Integer.parseInt(this.value));
}
}else if("double".equalsIgnoreCase(type)){
if(this.value.matches("\\d+(\\.\\d+)?")){
setMet.invoke(this.currentObj,Double.parseDouble(this.value));
}
}else if("String".equalsIgnoreCase(type)){
setMet.invoke(this.currentObj,this.value);
}else if("date".equalsIgnoreCase(type)){
if(this.value.matches("\\d{4}-\\d{2}-\\d{2}")){
setMet.invoke(this.currentObj,new SimpleDateFormat("yyyy-MM-dd")
.parse(this.value));
}
if(this.value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")){
setMet.invoke(this.currentObj,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.parse(this.value));
}
}else if("string[]".equalsIgnoreCase(type)){ //字符串数组
setMet.invoke(this.currentObj,new Object[]{this.arrayValue});
}else if("double[]".equals(type)){
double temp[]=new double[this.arrayValue.length];
for(int x=0;x<temp.length;x++){
if(this.arrayValue[x].matches("\\d+(\\.\\d+)?")){
temp[x]=Double.parseInt(this.arrayValue[x]);
}
}
setMet.invoke(this.currentObj,new Object[]{temp});
}else if("Double[]".equals(type)){
Double temp[]=new Double[this.arrayValue.length];
for(int x=0;x<temp.length;x++){
if(this.arrayValue[x].matches("\\d+(\\.\\d+)?")){
temp[x]=Double.parseInt(this.arrayValue[x]);
}
}
setMet.invoke(this.currentObj,new Object[]{temp});
}
}catch(Exception e){
e.printStackTrace();
}
}
}
以上就是极悦小编介绍的"Java反射自动赋值详解",希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为您服务。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习