项目--苍穹外卖

1.| constant | 存放相关常量类 |
| context | 存放上下文类 |
| enumeration | 项目的枚举类存储 |
| exception | 存放自定义异常类 |
| json | 处理json转换的类 |
| properties | 存放SpringBoot相关的配置属性类 |
| result | 返回结果类的封装 |
| utils | 常用工具类 |
2.| Entity | 实体,通常和数据库中的表对应 |
| DTO | 数据传输对象,通常用于程序中各层之间传递数据 |
| VO | 视图对象,为前端展示数据提供的对象 |

| POJO | 普通Java对象,只有属性和对应的getter和setter |

3.| config | 存放配置类 |
| controller | 存放controller类 |
| interceptor | 存放拦截器类 |
| mapper | 存放mapper接口 |
| service | 存放service类 |
| SkyApplication | 启动类 |

3.先编译一下,然后正常运行

项目--苍穹外卖_第1张图片

 前后端联调:

nginx反向代理,就是将前端发送的动态请求由nginx转发到后端服务器

好处: 

前端发送的请求,是如何请求到后端服务的?

在使用Nginx作为反向代理的Java项目中,前端发送的请求会被Nginx接收并处理,然后转发给后端服务。以下是一些基本步骤:

客户端(前端)发送请求到Nginx服务器。
Nginx服务器接收请求,并根据配置的规则进行处理。
Nginx根据配置的规则将请求转发给后端服务。
后端服务接收到请求并处理,然后返回响应。
Nginx接收后端服务的响应,并将其返回给客户端。

在这个过程中,Nginx扮演了反向代理的角色,接收客户端的请求并转发给后端服务,同时也将后端服务的响应返回给客户端。通过Nginx,可以实现对请求的负载均衡(把大量的请求按照我们指定的方式均衡的分配给集中的每台服务器)、缓存、安全过滤等处理,提高系统的性能和安全性。 

配置:nginx.conf

server{     

             listen 80;     

             server_name localhost;          

             location /api/ {                     

                             proxy_pass   http://localhost:8080/admin/;  #反向代理     } }

nginx 负载均衡的配置方式: nginx.conf

upstream webservers{     

                server 192.168.100.128:8080;     

                server 192.168.100.129:8080;

}

server{     listen 80;     

                server_name localhost;          

                location /api/ {                   

                                proxy_pass   http://webservers/admin/;  #负载均衡     } }

项目--苍穹外卖_第2张图片

完善登录功能

问题:员工表中的密码是明文存储,安全性太低。 

1.将密码加密后存储,提高安全性

2.使用MD5加密方式对明文密码加密

1.修改数据库中明文密码,改为MD5加密后的密文

2.修改Java代码,前端提交的密码进行MD5加密后再跟数据库中密码比对

在EmployeeServiceImpl中

//进行md5加密,然后再进行比对

password = DigestUtils.md5DigestAsHex(password.getBytes());

if (!password.equals(employee.getPassword())) {    

//密码错误  

throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR); }

前后端 分离开发流程:

项目--苍穹外卖_第3张图片

导入接口文档 

json导入YApi

Yapi 是设计阶段使用的工具,管理和维护接口

Swagger 在开发阶段使用的框架,帮助后端开发人员做后端的接口测试

Swagger

使用Swagger你只需要按照它的规范去定义接口及接口相关的信息,就可以做到生成接口文档,以及在线接口调试页面。

Knife4j 是为Java MVC框架集成Swagger生成Api文档的增强解决方案。

1.导入maven坐标

2.在配置类中加入knnife4j相关配置

3.设置静态资源映射,否则接口文档页面无法访问

           

com.github.xiaoymin            

knife4j-spring-boot-starter            

3.0.2

 WebMvcConfiguration中:

@Bean

public Docket docket(){    

    ApiInfo apiInfo = new ApiInfoBuilder()            

                .title(“苍穹外卖项目接口文档”)            

                .version(“2.0”)            

                .description(“苍穹外卖项目接口文档")            

                .build();    

Docket docket = new Docket(DocumentationType.SWAGGER_2)            

           .apiInfo(apiInfo)            

           .select()            

           //指定生成接口需要扫描的包      .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))                          .paths(PathSelectors.any())            

        .build();

return  docket;

}

/* * 
*设置静态资源映射 ,主要是访问接口文档
* @param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
   log.info(“开始设置静态资源映射...");   
   registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");    
   registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
   }

常用注解:

通过注解可以控制生成的接口文档,使接口文档拥有更好的可读性,常用注解如下:

项目--苍穹外卖_第4张图片

@Api(tags ="员工相关接口")

@ApiOperation(value = "员工登录")    方法上

@ApiOperation("员工退出")

DTO:专注于做数据传输

当前端提交的数据和实体类中对应的属性差别比较大时,建议使用DTO来封装数据

VO

新增员工

@PostMapping
@ApiOperation("新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO){
log.info("新增员工:{}",employeeDTO);
employeeService.save(employeeDTO);
return Result.success();
}

void save(EmployeeDTO employeeDTO); 

@Override
public void save(EmployeeDTO employeeDTO) {
Employee employee = new Employee();
//employee.setName(employeeDTO.getName());

//对象属性拷贝
BeanUtils.copyProperties(employeeDTO,employee);
//设置账号的状态,默认正常状态1表示正常,0表示锁定
employee.setStatus(StatusConstant.ENABLE);

//设置密码,默认123456
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.

DEFAULT_PASSWORD.getBytes()));

//设置当前记录的创建时间和修改时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());

//设置当前记录创建人id和修改人id
//TODO 后期需要改为当前登录用户的id
employee.setCreateUser(10L);
employee.setUpdateUser(10L);

employeeMapper.insert(employee);
}

  

@Insert("insert into employee (name,username,password,phone,sex,id_number,create_time,update_time," +
"create_user,update_user)" +"values "+
"(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser})")
void insert(Employee employee);

项目--苍穹外卖_第5张图片

 项目--苍穹外卖_第6张图片

项目--苍穹外卖_第7张图片

存在问题

1.录入的用户名已存在,抛出异常后没有处理

2.新增员工时,创建人id和修改人id设置为了固定值 

@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex) {
log.error("异常信息:{}", ex.getMessage());
Duplicate entry 'zhangsan' for key 'employee.idx username
String message = ex.getMessage(); //获得异常信息
if (message.contains("Duplicate entry")) { //判断异常信息里面有没有关键字Duplicate entry
String[] split = message.split(" "); //动态把字符串提取出来,根据空格分割,得到数组对象
String username = split[2]; //第三个,下标为2
String msg = username + MessageConstant.ALREADY_EXISTS; //用户名已存在
return Result.error(msg);
} else {
return Result.error(MessageConstant.UNKNOWN_ERROR);
}
}

项目--苍穹外卖_第8张图片

项目--苍穹外卖_第9张图片 项目--苍穹外卖_第10张图片

解析出登录员工id后,如何传递给Service的save方法?

ThreadLocal 并不是一个Thread,而是Thread的局部变量。

ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

ThreadLocal常用方法:

public void set(T value)     设置当前线程的线程局部变量的值

public T get()         返回当前线程所对应的线程局部变量的值

public void remove()        移除当前线程的线程局部变量 

注意:客户端发送的每次请求,后端的Tomcat服务器都会分配一个单独的线程来处理请求

项目--苍穹外卖_第11张图片

项目--苍穹外卖_第12张图片

项目--苍穹外卖_第13张图片

员工分页查询

业务规则:

根据页码展示员工信息

每页展示10条数据

分页查询时可以根据需要,输入员工姓名进行查询

项目--苍穹外卖_第14张图片

项目--苍穹外卖_第15张图片

返回数据data:

total:总记录数   records:代表当前这一页要展示的数据集合,数据多个,为数组

根据分页查询接口设计对应的DTO:

@Data

public class EmployeePageQueryDTO implements Serializable {    

//员工姓名    

private String name;    

//页码    

private int page;    

//每页显示记录数     private int pageSize;

}

后面所有的分页查询,统一都封装成PageResult对象:

/**  * 封装分页查询结果  */

@Data

@AllArgsConstructor

@NoArgsConstructor

public class PageResult implements Serializable {    

private long total; //总记录数    

private List records; //当前页数据集合 }

员工信息分页查询后端返回的对象类型为:Result

@GetMapping("/page")
@ApiOperation("员工分页查询")
public Result page(EmployeePageQueryDTO employeePageQueryDTO){
log.info("员工分页查询,参数为:{}",employeePageQueryDTO); //输出
PageResult pageResult =employeeService.pageQuery(employeePageQueryDTO);
return Result.success(pageResult);
}

PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO); 

@Override
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
//select * from employee limit 0,10
//开始分页查询
PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());

Page page =employeeMapper.pageQuery(employeePageQueryDTO);
long total = page.getTotal(); //总记录数
List records = page.getResult(); //records
return new PageResult(total,records);
}

Page pageQuery(EmployeePageQueryDTO employeePageQueryDTO); 

  


"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >


日期格式 错误:

解决方式: 方式一:在属性上加入注解,对日期进行格式化

方式二:在 WebMvcConfiguration 中扩展Spring MVC的消息转换器,统一对日期类型进行格式化处理

配置类上

@Override
protected void extendMessageConverters(List> converters) {
log.info("扩展消息转换器...");
//创建一个消息转换器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//需要为消息转换器设置一个对象转换器,对象转换器可以将java对象序列化为json数据
converter.setObjectMapper(new JacksonObjectMapper());
//将自己的消息转换器加入容器中
converters.add(0,converter); //优先使用
}

启用禁用员工账号

业务规则: 可以对状态为“启用” 的员工账号进行“禁用”操作 可以对状态为“禁用”的员工账号进行“启用”操作 状态为“禁用”的员工账号不能登录系统

根据接口设计中的请求参数形式对应的在 EmployeeController 中创建启用禁用员工账号的方法:

@PostMapping("/status/{status}")
@ApiOperation("启用禁用员工账号")
public Result startStop(@PathVariable Integer status, Long id) {
log.info("启用禁用员工账号:{},{}", status, id);
employeeService.startOrStop(status, id);
return Result.success();
}

在 EmployeeService 接口中声明启用禁用员工账号的业务方法:

void startOrStop(Integer status, Long id);

 在 EmployeeServiceImpl 中实现启用禁用员工账号的业务方法:

@Override
public void startOrStop(Integer status, Long id) {
// Employee employee = new Employee();
// employee.setStatus(status);
// employee.setId(id);
Employee employee = Employee.builder()
.status(status)
.id(id)
.build();
//Update employee set status =?where id = ?
employeeMapper.update(employee);

}

在 EmployeeMapper 接口中声明 update 方法:

void updae(Employee employee);

在 EmployeeMapper.xml 中编写SQL:


update employee

name = #{name},
username = #{username},
password = #{password},
phone = #{phone},
sex = #{sex},
id_Number = #{idNumber},
update_Time = #{updateTime},
update_User = #{updateUser},
status = #{status},

where id = #{id}

编辑员工 

编辑员工功能涉及到两个接口: 根据id查询员工信息 编辑员工信息

在 EmployeeController 中创建 getById 方法:

@GetMapping("/{id}")
@ApiOperation("根据id查询员工信息")
public Result getById(@PathVariable Long id) {
Employee employee = employeeService.getById(id);
return Result.success(employee);
}

在 EmployeeService 接口中声明 getById 方法: 

Employee getById(Long id); 

在 EmployeeServiceImpl 中实现 getById 方法: 

@Override
public Employee getById(Long id) {
Employee employee=employeeMapper.getById(id);
employee.setPassword("****");
return employee;
}

在 EmployeeMapper 接口中声明 getById 方法: 

@Select("select *from employee where id = #{id}")
Employee getById(Long id);

 在 EmployeeController 中创建 update 方法:

@PutMapping
@ApiOperation("编辑员工信息")
public Result update(@RequestBody EmployeeDTO employeeDTO) {
log.info("编辑员工信息:{}", employeeDTO);
employeeService.update(employeeDTO);
return Result.success();
}

在 EmployeeService 接口中声明 update 方法: 

void update(EmployeeDTO employeeDTO);

 在 EmployeeServiceImpl 中实现 update 方法:

public void update(EmployeeDTO employeeDTO) {//通过DTO来接收前端提交过来的数据
//对象属性拷贝,给employee赋值
Employee employee = new Employee();
BeanUtils.copyProperties(employeeDTO, employee);
employee.setUpdateTime(LocalDateTime.now());
employee.setUpdateUser(BaseContext.getCurrentId());
employeeMapper.update(employee); //调用service方法
}

导入分类模块功能代码

项目--苍穹外卖_第16张图片

业务规则:

分类名称必须是唯一

分类按照类型可以分为菜品分类和套餐分类

新添加的分类状态默认为“禁用” 

接口设计: 新增分类 分类分页查询 根据id删除分类 修改分类 启用禁用分类 根据类型查询分类

项目--苍穹外卖_第17张图片 

你可能感兴趣的:(java)