文件下载:
文件下载介绍:
文件下载,也称为download,是指将文件从服务器传输到本地计算机的过程。
通过浏览器进行文件下载,通常有两种表现形式:
- 以附件形式下载,弹出保存对话框,将文件保存到指定磁盘目录
- 直接在浏览器中打开
通过浏览器进行文件下载,本质上就是服务端将文件以流的形式写回浏览器的过程。
文件下载代码开发:
在CommonController类中添加download方法
1、通过输入流读取文件内容
2、通过输出流将文件写回浏览器,在浏览器展示图片
3、关闭输入输出流,释放资源
/**
* 文件下载
* @param name
*/
@GetMapping("/download")
public void download(String name, HttpServletResponse response){
try {
//输入流,通过输入流读取文件内容
FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
//输出流,通过输出流将文件写回浏览器,在浏览器展示图片
ServletOutputStream outputStream = response.getOutputStream();
//代表图片文件
response.setContentType("image/jpeg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fileInputStream.read(bytes)) != -1){
outputStream.write(bytes,0,len);
outputStream.flush();
}
//关闭资源
outputStream.close();
fileInputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
新增菜品:
需求分析:
后台系统中可以管理菜品信息,通过新增功能来添加一个新的菜品,在添加菜品时需要选择当前菜品所属的菜品分类,并且需要上传菜品图片,在移动端会按照菜品分类来展示对应的菜品信息。
数据模型:
dish菜品表:
dish_flavor菜品口味表:
每当新增一个菜品,就会将前端传来的数据存入这两张表中。
代码开发:
在开发业务功能前,先将需要用到的类和接口基本结构创建好:
实体类DishFlavor
@Data
public class DishFlavor implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//菜品id
private Long dishId;
//口味名称
private String name;
//口味数据list
private String value;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
//是否删除
private Integer isDeleted;
}
Mapper接口DishFlavorMapper
@Mapper
public interface DishFlavorMapper extends BaseMapper<DishFlavor> {
}
业务层接口DishFlavorService
public interface DishFlavorService extends IService<DishFlavor> {
}
业务层实现类 DishFlavorServicelmpl
@Service
public class DishFlavorServiceImpl extends ServiceImpl<DishFlavorMapper, DishFlavor>implements DishFlavorService {
}
控制层 DishController
@RestController
@RequestMapping("/dish")
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private DishFlavorService dishFlavorService;
}
新增菜品时前端页面和服务端的交互流程:
1、页面(backend/page/food/add.html)发送ajax请求,请求服务端获取菜品分类数据并展示到下拉框中
2、页面发送请求进行图片上传,请求服务端将图片保存到服务器
3、页面发送请求进行图片下载,将上传的图片进行回显
4、点击保存按钮,发送ajax请求,将菜品相关数据以json形式提交到服务端
开发新增菜品功能,其实就是在服务端编写代码去处理前端页面发送的这4次请求即可。
分页查询:在CategoryController添加
/**
* 分页查询
* @param page
* @param pageSize
* @return
*/
@GetMapping("/page")
public R<Page> page(int page, int pageSize){
//分页构造器
Page<Category> pageInfo = new Page<>(page,pageSize);
//条件构造器
LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
//排序条件,根据sort进行排序
queryWrapper.orderByAsc(Category::getSort);
//进行分页查询
categoryService.page(pageInfo,queryWrapper);
return R.success(pageInfo);
}
启动项目,进入菜品管理,点击菜品分类下拉框,成功获得数据
接收页面提交的数据(涉及两张表)
点击保存按钮的时候,把前端的json数据提交到后台,后台接收数据,对数据进行处理;要与两张表打交道,一个是dish一个是dish_flavor表;
Dish实体类不满足接收flavor参数,我们需要导入DishDto,用于封装页面提交的数据
DTO
DTO,全称为Data Transfer Object,即数据传输对象,一般用于展示层与服务层之间的数据传输,封装页面提交的数据。
- 在reggie包下,创建一个新包为dto
- 在该包下创建DishDto 数据传输类
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 数据传输对象
*/
@Data
public class DishDto extends Dish {
private List<DishFlavor> flavors = new ArrayList<>();
private String categoryName;
private Integer copies;
}
新增菜品同时插入菜品对应的口味数据,需要操作两张表:dish、dishflavor
在DishService接口中添加方法saveWithFlavor,在DishServiceImpl实现
DishServiceImpl类:
@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
@Autowired
private DishFlavorService dishFlavorService;
/**
* 新增菜品,同时保存对应的口味数据
* @param dishDto
*/
@Transactional
public void saveWithFlavor(DishDto dishDto) {
//保存菜品的基本信息到菜品表dish
this.save(dishDto);
Long dishId = dishDto.getId();//菜品id
List<DishFlavor> flavors = dishDto.getFlavors();//菜品口味
flavors = flavors.stream().map((item) ->{
item.setDishId(dishId);
return item;
}).collect(Collectors.toList());
//保存菜品口味数据到菜品口味表dish_flavor
dishFlavorService.saveBatch(flavors);
}
}
@Transactional: 涉及到对多张表的数据进行操作,需要加事务,需要事务生效,需要在启动类加上事务注解生效。
在启动类开启事务: 加上 @EnableTransactionManagement这个注解
controller 层:
/**
* 菜品管理
*/
@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private DishFlavorService dishFlavorService;
/**
* 新增菜品
* @param dishDto
* @return
*/
@PostMapping
public R<String> save(@RequestBody DishDto dishDto){
log.info(dishDto.toString());
dishService.saveWithFlavor(dishDto);
R.success("新增菜品成功");
return null;
}
}