教学信息化大赛网站建设作品,电子商务网站运营与...,几十个必备的设计师灵感网站,如何用dreamer做网站目录
一、问题说明
二、前后端分离开发
1、介绍
2、开发流程
3、前端技术栈
三、Yapi
1、介绍
2、部署
3、使用
3.1 添加项目编辑 3.2 添加分类编辑
3.3 添加接口
3.4 运行
3.5 导出接口
3.6 导入数据
四、Swagger
1、介绍
2、使用方式 2.1 pom
2.2 导入…目录
一、问题说明
二、前后端分离开发
1、介绍
2、开发流程
3、前端技术栈
三、Yapi
1、介绍
2、部署
3、使用
3.1 添加项目编辑 3.2 添加分类编辑
3.3 添加接口
3.4 运行
3.5 导出接口
3.6 导入数据
四、Swagger
1、介绍
2、使用方式 2.1 pom
2.2 导入knife4j相关配置WebConfig
2.3 LoginCheckFilter设置不需要处理的请求路径
2.4 验证
2.5 调试接口
2.6 下载接口文档
3、常用注解
3.1 Setmeal实体添加注解 3.2 R 添加注解
3.3 SetmealController添加注解
五、项目部署
1、部署架构
2、部署环境说明
3、部署前端项目
3.1 第一步 3.2 第二步
4、部署后端项目
4.1 第一步 4.2 第二步 reggieStart.sh
4.3 第三步
六、图片报错问题
6.1 修改图片存储为linu目录并提交代码重新执行脚本文件
6.2 将本地img图片上传到Linux机器目录 前言前后端分离开发 一、问题说明 二、前后端分离开发
1、介绍 2、开发流程 3、前端技术栈 三、Yapi
1、介绍 2、部署
博主很久之前写的文章
3、使用 3.1 添加项目 3.2 添加分类
3.3 添加接口 3.4 运行 3.5 导出接口 3.6 导入数据 四、Swagger
1、介绍 2、使用方式 2.1 pom
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.runa/groupIdartifactIdreggie_take_out_spuer/artifactIdversion1.0-SNAPSHOT/versionpackagingjar/packagingparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.4.5/versionrelativePath/ !-- lookup parent from repository --/parentnamereggie_take_out_spuer/nameurlhttp://maven.apache.org/urlpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingjava.version1.8/java.version/propertiesdependencies!--阿里云短信服务--dependencygroupIdcom.aliyun/groupIdartifactIdaliyun-java-sdk-core/artifactIdversion4.5.16/version/dependencydependencygroupIdcom.aliyun/groupIdartifactIdaliyun-java-sdk-dysmsapi/artifactIdversion2.1.0/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdscopecompile/scope/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.4.2/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.20/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.76/version/dependencydependencygroupIdcommons-lang/groupIdartifactIdcommons-lang/artifactIdversion2.6/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-starter/artifactIdversion1.1.23/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion3.8.1/versionscopetest/scope/dependencydependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-spring-boot-starter/artifactIdversion3.0.2/version/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdversion2.4.5/version/plugin/plugins/build
/project2.2 导入knife4j相关配置WebConfig package com.runa.reggie.config;import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.runa.reggie.common.JacksonObjectMapper;
import com.runa.reggie.entity.Employee;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;Slf4j
Configuration
EnableSwagger2
EnableKnife4j
public class WebMvcConfig extends WebMvcConfigurationSupport {/*** 设置静态资源映射* param registry*/Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {log.info(~~~开始进行静态资源映射...~~);registry.addResourceHandler(doc.html).addResourceLocations(classpath:/META-INF/resources/);registry.addResourceHandler(/webjars/**).addResourceLocations(classpath:/META-INF/resources/webjars/);registry.addResourceHandler(/backend/**).addResourceLocations(classpath:/backend/);registry.addResourceHandler(/front/**).addResourceLocations(classpath:/front/);}/*** 扩展MVC框架的消息转换器* param converters*/Overrideprotected void extendMessageConverters(ListHttpMessageConverter? converters) {log.info(扩展消息转换器。。。。);// 创建消息转换器对象MappingJackson2HttpMessageConverter messageConverter new MappingJackson2HttpMessageConverter();//设置对象转换器底层使用Jackson将java对象转为jsonmessageConverter.setObjectMapper(new JacksonObjectMapper());//将上面的消息转换器对象追加到MVC框架转换器集合中converters.add(0,messageConverter);}Beanpublic Docket createRestApi() {// 文档类型return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage(com.runa.reggie.controller)).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title(瑞吉外卖).version(1.0).description(瑞吉外卖接口文档).build();}}2.3 LoginCheckFilter设置不需要处理的请求路径 package com.runa.reggie.filter;import com.alibaba.fastjson.JSON;
import com.runa.reggie.common.BaseContext;
import com.runa.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;Slf4j
WebFilter(filterName loginCheckFilter, urlPatterns /*)
public class LoginCheckFilter implements Filter {// 路径匹配器public static final AntPathMatcher PATH_MATCHER new AntPathMatcher();Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request (HttpServletRequest) servletRequest;HttpServletResponse response (HttpServletResponse) servletResponse;// 1 获取本次请求的URI// request.getRequestURL()返回的是全路径。// request.getRequestURI()返回的是除去协议域名IP端口号之后的路由部分。String requestURI request.getRequestURI();log.info(拦截到请求【{}】,requestURI);// 定义一些不需要处理的路径String[] urls new String[]{/employee/login,/employee/logout,/backend/**,/front/**,/common/**,/user/sendMsg,/user/login,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs};// 2 判断本次请求是否需要处理boolean check check(urls, requestURI);// 3 如果不需要处理,则直接放行if(check){log.info(本次请求【 {} 】 不需要处理,requestURI);filterChain.doFilter(request,response);return;}// 4 -1员工端 判断登录状态如果已登录则直接放行if(request.getSession().getAttribute(employee) ! null){log.info(用户已登录请求url为【{}】, 用户id为:【 {} 】 ,requestURI,request.getSession().getAttribute(employee));// 获取ID 塞进线程Long empId (Long) request.getSession().getAttribute(employee);BaseContext.setCurrentId(empId);filterChain.doFilter(request,response);return;}// 4 -2移动端 判断登录状态如果已登录则直接放行if(request.getSession().getAttribute(user) ! null){log.info(用户已登录请求url为【{}】, 用户id为:【 {} 】 ,requestURI,request.getSession().getAttribute(user));// 获取ID 塞进线程Long userId (Long) request.getSession().getAttribute(user);BaseContext.setCurrentId(userId);filterChain.doFilter(request,response);return;}log.info(用户未登录);// 5 如果未登录则返回未登录结果通过输出流方式向客户端页面响应数据response.getWriter().write(JSON.toJSONString(R.error(NOTLOGIN)));return;}/*** 路径匹配检查本次请求是否需要放行* param urls* param requestURI* return*/public boolean check(String[] urls, String requestURI){for (String url : urls) {boolean match PATH_MATCHER.match(url, requestURI);if(match){return true;}}// 循环都匹配不上就返回falsereturn false;}
}2.4 验证
启动服务
http://localhost:8080/doc.html 2.5 调试接口
这里存在需要登录问题这里先登录一下再调试 2.6 下载接口文档 3、常用注解 3.1 Setmeal实体添加注解
package com.runa.reggie.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;/*** 套餐*/
Data
ApiModel(套餐)
public class Setmeal implements Serializable {private static final long serialVersionUID 1L;ApiModelProperty(主键)private Long id;//分类idApiModelProperty(分类ID)private Long categoryId;//套餐名称ApiModelProperty(套餐名称)private String name;//套餐价格ApiModelProperty(套餐价格)private BigDecimal price;//状态 0:停用 1:启用ApiModelProperty(状态)private Integer status;//编码ApiModelProperty(编码)private String code;//描述信息ApiModelProperty(描述信息)private String description;//图片ApiModelProperty(图片)private String image;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;
}3.2 R 添加注解
package com.runa.reggie.common;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;/*** 通用返回结果服务端响应的数据最终都会封装成此对象* param T*/
Data
ApiModel(返回结果)
public class RT {ApiModelProperty(编码)private Integer code; //编码1成功0和其它数字为失败ApiModelProperty(错误信息)private String msg; //错误信息ApiModelProperty(数据)private T data; //数据ApiModelProperty(动态数据)private Map map new HashMap(); //动态数据public static T RT success(T object) {RT r new RT();r.data object;r.code 1;return r;}public static T RT error(String msg) {R r new R();r.msg msg;r.code 0;return r;}public RT add(String key, Object value) {this.map.put(key, value);return this;}}3.3 SetmealController添加注解 package com.runa.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.runa.reggie.common.R;
import com.runa.reggie.dto.SetmealDto;
import com.runa.reggie.entity.Category;
import com.runa.reggie.entity.Setmeal;
import com.runa.reggie.service.CategoryService;
import com.runa.reggie.service.SetmealDishService;
import com.runa.reggie.service.SetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;
import java.util.stream.Collectors;RestController
RequestMapping(/setmeal)
Slf4j
Api(tags 套餐相关接口)
public class SetmealController {Autowiredprivate SetmealService setmealService;Autowiredprivate CategoryService categoryService;Autowiredprivate SetmealDishService setmealDishService;/*** 新增套餐* param setmealDto* return*/PostMappingApiOperation(value 新增套餐接口)public RString save(RequestBody SetmealDto setmealDto){log.info(套餐信息{},setmealDto);setmealService.saveWithDish(setmealDto);return R.success(新增套餐成功);}/*** 套餐分页查询* param page* param pageSize* param name* return*/GetMapping(/page)ApiOperation(value 套餐分页查询)ApiImplicitParams({ApiImplicitParam(name page, value 页码, required true),ApiImplicitParam(name pageSize, value 每页记录数, required true),ApiImplicitParam(name name, value 套餐名称, required false)})public RPage page(int page, int pageSize, String name){//分页构造器对象PageSetmeal pageInfo new Page(page,pageSize);PageSetmealDto dtoPage new Page();LambdaQueryWrapperSetmeal queryWrapper new LambdaQueryWrapper();//添加查询条件根据name进行like模糊查询queryWrapper.like(name ! null,Setmeal::getName,name);//添加排序条件根据更新时间降序排列queryWrapper.orderByDesc(Setmeal::getUpdateTime);setmealService.page(pageInfo,queryWrapper);//对象拷贝BeanUtils.copyProperties(pageInfo,dtoPage,records);ListSetmeal records pageInfo.getRecords();ListSetmealDto list records.stream().map((item) - {SetmealDto setmealDto new SetmealDto();//对象拷贝BeanUtils.copyProperties(item,setmealDto);//分类idLong categoryId item.getCategoryId();//根据分类id查询分类对象Category category categoryService.getById(categoryId);if(category ! null){//分类名称String categoryName category.getName();setmealDto.setCategoryName(categoryName);}return setmealDto;}).collect(Collectors.toList());dtoPage.setRecords(list);return R.success(dtoPage);}/*** 删除套餐* param ids* return*/DeleteMappingApiOperation(value 删除套餐接口)public RString delete(RequestParam ListLong ids){log.info(ids:{},ids);setmealService.removeWithDish(ids);return R.success(套餐数据删除成功);}/*** 根据条件查询套餐数据* param setmeal* return*/GetMapping(/list)ApiOperation(value 根据条件查询套餐数据接口)public RListSetmeal list(Setmeal setmeal){LambdaQueryWrapperSetmeal queryWrapper new LambdaQueryWrapper();queryWrapper.eq(setmeal.getCategoryId() ! null,Setmeal::getCategoryId,setmeal.getCategoryId());queryWrapper.eq(setmeal.getStatus() ! null,Setmeal::getStatus,setmeal.getStatus());queryWrapper.orderByDesc(Setmeal::getUpdateTime);ListSetmeal list setmealService.list(queryWrapper);return R.success(list);}}五、项目部署
1、部署架构 2、部署环境说明 3、部署前端项目
3.1 第一步 3.2 第二步 4、部署后端项目
4.1 第一步 4.2 第二步 reggieStart.sh #!/bin/sh
echo
echo 自动化部署脚本启动
echo echo 停止原来运行中的工程
APP_NAMEreggie_take_outtpidps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk {print $2}
if [ ${tpid} ]; thenecho Stop Process...kill -15 $tpid
fi
sleep 2
tpidps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk {print $2}
if [ ${tpid} ]; thenecho Kill Process!kill -9 $tpid
elseecho Stop Success!
fiecho 准备从Git仓库拉取最新代码
cd /usr/local/javaapp/reggie_take_outecho 开始从Git仓库拉取最新代码
git pull
echo 代码拉取完成echo 开始打包
outputmvn clean package -Dmaven.test.skiptruecd targetecho 启动项目
nohup java -jar reggie_take_out-1.0-SNAPSHOT.jar reggie_take_out.log
echo 项目启动完成
4.3 第三步 六、图片报错问题
tail -f reggie_take_out.log 6.1 修改图片存储为linu目录并提交代码重新执行脚本文件 6.2 将本地img图片上传到Linux机器目录