本项目为黑马javaweb学习笔记 该项目采取了springboot框架,是该框架的初步应用。 数据存储在xml文件之中,并没有使用数据库。
- 该项目使用技术
- springboot进行请求响应以及数据处理封装
- dom4j负责处理xml文件中存储的数据
- 三层解耦
- IOC(控制反转)和DI(依赖注入)
- 首先是项目目录结构
该项目为一个标准的maven项目结构
- controller负责响应请求
- dao负责处理数据
- server负责业务逻辑处理
- pojo负责存储项目需要用到的公共类
- dao代码及解析
- 首先是负责解析xml文件的代码
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import springruest.pojo.Emp;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class XmlParse {
public static List<Emp> parse(String file){
ArrayList<Emp> res = new ArrayList<>();
try{
File fr = new File(file);
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(fr);
Element root = document.getRootElement();
List<Element> rootElement = root.elements();
for(Element e:rootElement){
Emp emp = new Emp();
emp.setName(e.element("name").getText());
emp.setAge(Integer.parseInt(e.element("age").getText()));
emp.setImage(e.element("image").getText());
emp.setGender(e.element("gender").getText());
emp.setJob(e.elementText("job"));
res.add(emp);
}
}catch (Exception e){
System.out.println("error");
}
return res;
}
public static void main(String[] args) {
XmlParse xmlParse = new XmlParse();
List<Emp> res = xmlParse.parse("resources\emp.xml");
for (Emp e : res){
System.out.println(e);
}
}
}
xml具体文档如下
<?xml version="1.0" encoding="UTF-8" ?>
<emps>
<emp>
<name>j</name>
<age>55</age>
<image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/1.jpg</image>
<!-- 1: 男, 2: 女 -->
<gender>1</gender>
<!-- 1: 讲师, 2: 班主任 , 3: 就业指导 -->
<job>1</job>
</emp>
<emp>
<name>b</name>
<age>65</age>
<image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/2.jpg</image>
<gender>1</gender>
<job>1</job>
</emp>
<emp>
<name>q</name>
<age>45</age>
<image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/3.jpg</image>
<gender>1</gender>
<job>2</job>
</emp>
<emp>
<name>z</name>
<age>38</age>
<image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/4.jpg</image>
<gender>2</gender>
<job>3</job>
</emp>
</emps>
接下来是EmpDao的代码,实际上就是解析XML的代码+一个进行将该类的对象注入容器之中的代码
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Repository;
import springruest.pojo.Emp;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
//@Component将该类的对象注入容器之中
@Repository(value = "Ea")
//@Repository(value = "Ea")可以通过value进行指定对象名,不指定默认类名首字母小写
public class EmpDao {
public static List<Emp> parse(String file){
ArrayList<Emp> res = new ArrayList<>();
try{
File fr = new File(file);
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(fr);
Element root = document.getRootElement();
List<Element> rootElement = root.elements();
for(Element e:rootElement){
Emp emp = new Emp();
emp.setName(e.element("name").getText());
emp.setAge(Integer.parseInt(e.element("age").getText()));
emp.setImage(e.element("image").getText());
emp.setGender(e.element("gender").getText());
emp.setJob(e.elementText("job"));
res.add(emp);
}
}catch (Exception e){
System.out.println("error");
}
return res;
}
public static void main(String[] args) {
XmlParse xmlParse = new XmlParse();
List<Emp> res = xmlParse.parse("resources\emp.xml");
for (Emp e : res){
System.out.println(e);
}
}
}
Resulet负责统一相应格式,其中的data会在响应时自动封装为JSON格式的数据
public class Result {
private Integer code ;//1 成功 , 0 失败
private String msg; //提示信息
private Object data; //数据 date
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);
}
}
User只是简单的封装员工对象的实体类,需要注意的是,数据库中的变量常用_而实体类中场用驼峰命名法,变量名不一致无法进行正确的数据封装,需要在配置中开启自动转换
public class User {
private String name;
private Integer age;
private Address address;
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 Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
", address=" + address +
'}';
}
}
RequestExample展示了Spring对于不同类型的数据,对应的处理方法
package springruest.RequestExample;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class address{
private String province = "";
private String city = "";
public address() {
}
@Override
public String toString() {
return "address{" +
"province='" + province + ''' +
", city='" + city + ''' +
'}';
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
class User{
private String name ="";
private int age = 0;
private address addr =null;
String[] hobby;
List<String> classGrid = new ArrayList<>();
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public address getAddr() {
return addr;
}
public void setAddr(address addr) {
this.addr = addr;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
public void setClassGrid(List<String> classGrid) {
this.classGrid = classGrid;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
", addr=" + addr +
", hobby=" + Arrays.toString(hobby) +
", classGrid=" + classGrid +
'}';
}
}
class nowDate{
private LocalDateTime localDateTime;
public LocalDateTime getLocalDateTime() {
return localDateTime;
}
public void setLocalDateTime(LocalDateTime localDateTime) {
this.localDateTime = localDateTime;
}
@Override
public String toString() {
return "nowDate{" +
"localDateTime=" + localDateTime +
'}';
}
}
@RestController
public class RequestExample {
//最原始的请求方法,解析复杂,现在已经废弃
// @RequestMapping("/simpleParam")
// public String simpleParam(HttpServletRequest request){
// String name = request.getParameter("name");
// String age = request.getParameter("age");
// System.out.println(name+age);
// return "ok";
// }
@RequestMapping("/simpleParam")
//Spring会自动进行类型转换,无论是get还是post只需要请求名一致即可
//或者变量名不一致但是可以进行参数映射,且使用@RequestParam以后,该参数必须传递required默认为ture
public String simpleParam(@RequestParam(name = "name",required = false) String uname, Integer age){
System.out.println(uname+age);
return "ok";
}
//spring默认是对数组进行赋值,所以要使用@RequestParam进行转换,不转换会报错
//http://localhost:8080/simpleList?list=1&list=2
@RequestMapping("/simpleList")
public List<String> simpleList(@RequestParam List<String> list){
System.out.println(list);
return list;
}
@RequestMapping("/complexClass/{id}/{name}")
//json格式使用类对象来进行接受,且key和变量名必须一致,json只能使用post
//http://localhost:8080/complexClass?classGrid=1&classGrid=2&classGrid=3&name=tom&age=12&addr.province=jilin&addr.city=baishan&hobby=a&hobby=b
//但是当List位于类中时,无需转换
//想要接受json格式的数据,必须用@RequestBody
// {
// "name":"tom",
// "age":10,
// "addr":{
// "province":"jilin",
// "city":"baishan"
// },
// "hobby":["1","2","3"],
// "classGrid":["a","b"]
// }
//路径参数可以有多个,必须使用@PathVariable,且参数名必须要上下一致
public String complexClass(@RequestBody User user, @PathVariable Integer id,@PathVariable String name){
System.out.println(user);
System.out.println(user.getAddr().toString());
return String.valueOf(id)+name;
}
@RequestMapping("/time")
public LocalDateTime time(@DateTimeFormat(pattern = "yyyy-MM-dd HH-mm-ss") LocalDateTime localDateTime){
System.out.println(localDateTime);
return localDateTime;
}
}
server包负责业务逻辑处理,需要把dao层的原始数据处理成前端需要的格式
- 首先是定义一个接口
import springruest.pojo.Emp;
import java.util.List;
public interface EmpServer {
public List<Emp> Emp();
}
imo包下为该接口的两个具体的实现类
- EmpServerA
package springruest.server.imo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import springruest.pojo.Emp;
import springruest.server.EmpServer;
import springruest.dao.EmpDao;
import java.util.List;
@Primary
//优先生效
@Service
//当存在两个同样目的服务时,可以通过@Component选择将哪个对象注入容器
//@Component存在三个衍生注解@Controller,@Service,@Repository分别用于控制器,业务类,数据访问的Dao层中
//@Repository与mybatis整合,用的少
//@Controller与@ResponseBody整合成@RestController了
public class EmpServerA implements EmpServer {
@Autowired
private EmpDao empDao;
@Override
public List<Emp> Emp() {
List<Emp> EmpList = EmpDao.parse("resources\emp.xml");
for(Emp e: EmpList){
if(e.getGender().equals("1") ){
e.setGender("男");
}else{
e.setGender("女");
}
if(e.getJob().equals("1")){
e.setJob("讲师");
}else if(e.getJob().equals("2")){
e.setJob("班主任");
}else{
e.setJob("就业指导");
}
}
System.out.println(EmpList);
return EmpList;
}
public static void main(String[] args) {
var emp = new EmpServerA();
System.out.println(emp.Emp());
}
}
- EmpServerB
package springruest.server.imo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import springruest.pojo.Emp;
import springruest.server.EmpServer;
import springruest.dao.EmpDao;
import java.util.List;
@Component
public class EmpServerB implements EmpServer {
@Autowired
private EmpDao empDao;
@Override
public List<Emp> Emp() {
List<Emp> EmpList = EmpDao.parse("resources\emp.xml");
for(Emp e: EmpList){
if(e.getGender().equals("1") ){
e.setGender("man");
}else{
e.setGender("wowan");
}
if(e.getJob().equals("1")){
e.setJob("讲师");
}else if(e.getJob().equals("2")){
e.setJob("班主任");
}else{
e.setJob("就业指导");
}
}
System.out.println(EmpList);
return EmpList;
}
public static void main(String[] args) {
var emp = new EmpServerA();
System.out.println(emp.Emp());
}
}
- EmpControllor 由于@Autowired默认是按照类型注入,所以如果没有额外指定优先级,那么将按照字母顺序去查找对应接口的实现类,就比如下列代码中的
@Autowired
private EmpServer empServer ;
将会默认该实现类为empServerA
package springruest.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springruest.pojo.Result;
import springruest.server.EmpServer;
@RestController
public class EmpControllor {
//@Resource可以指定注入bean的对象的名字
// @Resource(name = "empServerB")//优先度最高
//@Resource由JDk提供而@Autowired由spring提供
//@Resource默认由名称提供而@Autowired默认由类型提供
//可以利用该注解将容器之中的对象交给变量
//@Autowired默认是根据类进行注入
//同类型只允许一个注入
//可以通过@Primary,@Qualifier,@Resource解决
//@Primary指定优先选择的类
@Autowired
private EmpServer empServer ;
@RequestMapping("/EmpList")
public Result EmpList(){
var res = new Result().success(empServer.Emp());
return res;
}
}
最后是pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringRuest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringRuest</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.4</version>
</plugin>
</plugins>
</build>
</project>