文章开始前,先给大家看一张图,这是黑马javaweb-day05请求响应实例,也是第一个实现了前后端交互,这是我画的流程图,搞懂了前后端是如何交互的.(文件的所有路径不能出现中文,否则会报错,这个我暂时不知道该怎么解决).
那么这里面涉及到的东西,除了emp.html这是已经提供了的前端页面(其实也不难写,用element写一个表格),还有listemp和browser,其它是这篇文章中我们要重点实现的.
先来看Emp,这是一个类,它包含表格当中的五个信息:name,age,image,gender,job,这很容易实现
1.Emp
public class Emp {private String name;private Integer age;private String image;private String gender;private String job;public Emp() {}public Emp(String name, Integer age, String image, String gender, String job) {this.name = name;this.age = age;this.image = image;this.gender = gender;this.job = job;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getImage() {return image;}public void setImage(String image) {this.image = image;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}@Overridepublic String toString() {return "Emp{" +"name='" + name + '\'' +", age=" + age +", image='" + image + '\'' +", gender='" + gender + '\'' +", job='" + job + '\'' +'}';}
}
当然如果你觉得太长了可以使用lombok,这是后面课程的内容,懂的同学可以看一下下面的实现,不懂的可以直接跳到2
1.首先引入依赖
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>
//不用写版本,springboot自动集成并管理
2.改造Emp,一下子就简洁多了
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {private String name;private Integer age;private String image;private String gender;private String job;
}
2.result
这个方法我记得在前面的课程已经学过,是一个规范来的,code,msg,和data三个属性
code:表示接口调用的状态码,通常用于标识接口调用的结果状态,例如成功、失败等。在这里,使用整数类型(Integer)来表示状态码。通常约定,状态码为1表示成功,0或其他值表示失败。
msg:表示接口调用的消息,通常用于描述接口调用的结果信息,例如成功时可以是"success",失败时可以是具体的错误信息。在这里,使用字符串类型(String)来表示消息。
public class Result {private Integer code;private String msg;private Object data;public Result(){}public Result(Integer code,String msg,Object data){this.code=code;this.msg=msg;this.data=data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public static Result success(Object data){return new Result(1,"success",data);}public static Result success(){return new Result(1,"success",null);}public static Result error(String msg){return new Result(0,msg,null);}@Overridepublic String toString() {return "Result{" +"code=" + code +", msg='" + msg + '\'' +", data=" + data +'}';}
}
这里我同样提供lombok的简化书写
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {private Integer code;private String msg;private Object data;public static Result success(Object data){return new Result(1,"success",data);}public static Result success(){return new Result(1,"success",null);}public static Result error(String msg){return new Result(0,msg,null);}
}
3. XmlParserUtils
这个其实黑马的资料里给了,但是我还是想说一下里面的内容
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;public class XmlParserUtils {public static <T> List<T> parse(String file , Class<T> targetClass) {ArrayList<T> list = new ArrayList<T>(); //封装解析出来的数据try {//1.获取一个解析器对象SAXReader saxReader = new SAXReader();//2.利用解析器把xml文件加载到内存中,并返回一个文档对象Document document = saxReader.read(new File(file));//3.获取到根标签,获取empsElement rootElement = document.getRootElement();//4.通过根标签来获取 user 标签,获取emps中的empList<Element> elements = rootElement.elements("emp");//5.遍历集合,得到每一个 user 标签for (Element element : elements) {//获取 name 属性String name = element.element("name").getText();//获取 age 属性String age = element.element("age").getText();//获取 image 属性String image = element.element("image").getText();//获取 gender 属性String gender = element.element("gender").getText();//获取 job 属性String job = element.element("job").getText();//组装数据//指定构造函数,并关闭不能访问构造函数Constructor<T> constructor = targetClass.getDeclaredConstructor(String.class, Integer.class, String.class, String.class, String.class);constructor.setAccessible(true);//实例化T object = constructor.newInstance(name, Integer.parseInt(age), image, gender, job);//加到列表里list.add(object);}} catch (Exception e) {e.printStackTrace();}return list;}}
file里存的是文件的路径,targetClass是类对象(Emp).我们创建一个Arraylist<Emp>用来存最后解析出来的结构,还记得最开始的那张图吗,在这个实现里我们使用SAXReader来解析emp.xml获取了一个document类,然后通过拆分元素getRootElement获取了emps组件(这里我猜测拆分成了一颗树,emps是根节点),然后通过rootElement.elements("emp");获取所有的emp子元素,接下来通过遍历调用子元素的中的每一个文本element.element("name").getText();
然后我们通过getDeclaredConstructor(String.class, Integer.class, String.class, String.class, String.class);创造一个针对于Emp的构造函数,并用构造器Constructor来存储,setAccessible为true表示可以调用这个构造函数,通常我们是不能调用这个构造函数的,然后创建一个Emp使用构造函数构造并传参,放入list,最后返回list就得到了Emp所有元素的列表.
4.EmpController
@RestController
public class EmpController {@RequestMapping("/listEmp")public Result list(){//加载并解析XML文件//类->类加载器->找到类路径下的emp.xml->获取文件路径String file=this.getClass().getClassLoader().getResource("emp.xml").getFile();System.out.println(file);List<Emp>empList=com.yhw.utils.XmlParserUtils.parse(file, Emp.class);empList.stream().forEach(emp -> {//处理男和女String gender=emp.getGender();if("1".equals(gender)){emp.setGender("男");}else{emp.setGender("女");}String job=emp.getJob();if("1".equals(job)){emp.setJob("讲师");}else if("2".equals(job)){emp.setJob("班主任");}else{emp.setJob("就业指导");}});//调用result方法return Result.success(empList);}
}
首先说明RestController包含了Responsebody,所以当传输数据时会自动包装成json格式.,开头我们调用getclass获取对象,getclassloader获取类路径(我也不知道什么是类路径,我猜放在resource下他就能找到),它通常包含了xml,img等文件,所以通过它的getResource(文件名)就可以找到emp.xml,然后getfile获取完整路径,调用我们上面讲的XmlparserUtils来解析这个文件获取,由于Arraylist是list的接口,所以直接用list接受,然后我们拿到数据需要处理gender和job遍历list处理gender和job,最后返回Result包装的类对象,在上面我们指定了RequestMapping的路径/listEmp,现在已经映射到这个路径了使用postman是可以请求到数据的,好的后端的任务已经结束了,接下来略带讲一下前端.
5.frontend UI
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>员工信息</title>
</head><link rel="stylesheet" href="element-ui/index.css">
<script src="./js/vue.js"></script>
<script src="./element-ui/index.js"></script>
<script src="./js/axios-0.18.0.js"></script><body><h1 align="center">员工信息列表展示</h1><div id="app"><el-table :data="tableData" style="width: 100%" stripe border ><el-table-column prop="name" label="姓名" align="center" min-width="20%"></el-table-column><el-table-column prop="age" label="年龄" align="center" min-width="20%"></el-table-column><el-table-column label="图像" align="center" min-width="20%"><template slot-scope="scope"><el-image :src="scope.row.image" style="width: 80px; height: 50px;"></el-image></template></el-table-column><el-table-column prop="gender" label="性别" align="center" min-width="20%"></el-table-column><el-table-column prop="job" label="职位" align="center" min-width="20%"></el-table-column></el-table></div>
</body><style>.el-table .warning-row {background: oldlace;}.el-table .success-row {background: #f0f9eb;}
</style><script>new Vue({el: "#app",data() {return {tableData: []}},mounted(){axios.get('/listEmp').then(res=>{if(res.data.code){this.tableData = res.data.data;}});},methods: {}});
</script>
</html>
div标签里是一个element的表格,通过new Vue,el="#app"接管了div实现了双向绑定,在data()里我们定义了一恶搞tableData[]数组,表格数据来源data="tableData" ,在mounted(挂载实例的过程)生命中,我们通过axios异步请求then是处理成功后的回调函数,如果成功,且res.data.code状态码为1不为0,(注意第一个data是包含code,msg和data的)第二data是data里的data)执行完成后挂载到网页.