mysql
mysql-connector-java
runtime
@Configuration
@MapperScan("cn.skx.csmall.passport.mapper")
public class MybatisConfiguration {
public MybatisConfiguration(){
System.out.println("创建配置类: MybatisConfiguration" );
}
}
mybatis.mapper-locations=classpath/*.xml
spring.datasource.url=jdbc:mysql://localhost:3306/mall_ams?useUnicode=true&characterEncoding=utf-8&serveTimezone=Asia/Shanhai
spring.datasource.username=root
spring.datasource.password=root
mybatis.mapper-locations=classpath:mapper/*.xml
package cn.skx.csmall.passport.web;
/**
* 枚举
*/
public enum ServiceCode {
OK(20000),
ERR_NOT_FOUND(40400),
ERR_CONFLICT(40900);
private Integer value;
ServiceCode(Integer value){
this.value = value;
}
public Integer getValue(){
return value;
}
}
package cn.skx.csmall.passport.web;
import lombok.Data;
import java.io.Serializable;
/**
* 后端处理响应数据,返回数据类
*/
@Data
public class JsonResult implements Serializable {
/**
* 状态
*/
private Integer state;
/**
* 失败的提示信息
*/
//成功时没有这个,message 为 null时 不传
//@JsonInclude(JsonInclude.Include.NON_NULL)
private String message;
/**
* 成功
* @return 指定的响应内容
*/
public static JsonResult ok() {
JsonResult jsonResult = new JsonResult();
jsonResult.state = ServiceCode.OK.getValue();
return jsonResult;
}
/**
* 失败
* @param serviceCode 状态
* @param message 内容
* @return 指定的响应内容
*/
public static JsonResult fail(ServiceCode serviceCode, String message) {
JsonResult jsonResult = new JsonResult();
jsonResult.state = serviceCode.getValue();
jsonResult.message = message;
return jsonResult;
}
}
package cn.skx.csmall.passport.ex;
import cn.skx.csmall.passport.web.ServiceCode;
/**
* 业务异常
* @author sun
* @version 0.0.1
*/
public class ServiceException extends RuntimeException{
private ServiceCode serviceCode;
public ServiceCode getServiceCode() {
return serviceCode;
}
public ServiceException(ServiceCode serviceCode,String message){
super(message);
this.serviceCode = serviceCode;
}
}
package cn.skx.csmall.passport.ex.handler;
import cn.skx.csmall.passport.ex.ServiceException;
import cn.skx.csmall.passport.web.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局controller接口处理异常类
* @author sun
* @version 0.0.1
*/
@Slf4j
@RestControllerAdvice //单纯的使用 @controllerAdvice 响应的是文件名 + @ResponseBody 才可以返回字符串信息
public class GlobalExceptionHandler {
public GlobalExceptionHandler(){
System.out.println("全局异常处理器对象 : GlobalExceptionHandler");
}
/**
* 老祖宗异常 兜底的 ,让这个系统永远不会报 500 错误,异常一定会有人处理
* @param e 老祖宗异常
* @return 报错信息
*/
@ExceptionHandler
public String handleThrowable(Throwable e){
log.debug("捕获到Throwable:{}", e.getMessage());
e.printStackTrace();
return "服务器运行过程中出现未知错误,请联系系统管理员";
}
/**
* 自己声明的异常处理
* @param e 业务异常
* @return 报错信息
*/
@ExceptionHandler
public JsonResult handleServiceException(ServiceException e){
log.debug("捕获到ServiceException:{}", e.getMessage());
return JsonResult.fail(e.getServiceCode(),e.getMessage());
}
}
String phone = adminAddNewDTO.getPhone();
int count = adminMapper.countByphone(phone);
if(count != 0){
String message = "添加管理员失败,手机号【"+ phone +"】已经被占用";
throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
}
spring.jackson.default-property-inclusion=non_null
spring.profiles.active=dev
com.github.xiaoymin
knife4j-spring-boot-starter
2.0.9
package cn.skx.csmall.passport.config;
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
/**
* Knife4j配置类
*
* @author [email protected]
* @version 0.0.1
*/
@Slf4j
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfiguration {
/**
* 【重要】指定Controller包路径
*/
private String basePackage = "cn.skx.csmall.passport.controller";
/**
* 分组名称
*/
private String groupName = "product";
/**
* 主机名
*/
private String host = "http://java.tedu.cn";
/**
* 标题
*/
private String title = "酷鲨商城在线API文档--商品管理";
/**
* 简介
*/
private String description = "酷鲨商城在线API文档--商品管理";
/**
* 服务条款URL
*/
private String termsOfServiceUrl = "http://www.apache.org/licenses/LICENSE-2.0";
/**
* 联系人
*/
private String contactName = "Java教学研发部";
/**
* 联系网址
*/
private String contactUrl = "http://java.tedu.cn";
/**
* 联系邮箱
*/
private String contactEmail = "[email protected]";
/**
* 版本号
*/
private String version = "1.0.0";
@Autowired
private OpenApiExtensionResolver openApiExtensionResolver;
public Knife4jConfiguration() {
log.debug("加载配置类:Knife4jConfiguration");
}
@Bean
public Docket docket() {
String groupName = "1.0.0";
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.host(host)
.apiInfo(apiInfo())
.groupName(groupName)
.select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.any())
.build()
.extensions(openApiExtensionResolver.buildExtensions(groupName));
return docket;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(title)
.description(description)
.termsOfServiceUrl(termsOfServiceUrl)
.contact(new Contact(contactName, contactUrl, contactEmail))
.version(version)
.build();
}
}
knife4j.enable=true
//类上
@Api(tags = "01. 管理员模块")
//方法上
@ApiOperation(value = "新增管理员")
@ApiOperationSupport(order = 100)//升序排列
//参数为单个
@ApiImplictParam(name = "id",value = "相册的id",required = true,dataType = "long")
//参数为多个
@ApiImplictParams({
@ApiImplictParam(xxx),
@ApiImplictParam(xxx),
@ApiImplictParam(xxx)
})
http://localhost:9080/doc.html
@ApiModelProperty(value = "名称",required = true,example = "示例的相册")
@RequestBody 此注解加上
在线文档调试界面 不会显示请求参数的输入框,提供的是一个JSON字符串供编辑
前端传递的数据类型是 FormData类型的
name=jack&age=18&sex=男
后端就不能使用@RequestBody注解 api调试就是输入框
前端 formData 数据类型 和 后端注解 @RequestBody 互斥
npm i qs -S
import qs from 'qs';
Vue.prototype.qs = qs;
let formData = this.qs.stringify(this.ruleForm);
org.springframework.boot
spring-boot-starter-validation
在类上,方法上,方法参数前加上 @Validated 或者 @Valid 注解
一般是放在字段上实际底层代码这样的
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@NotNull(message = "添加相册失败,必须提叫相册名称")
package cn.skx.csmall.passport.config;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.validation.Validation;
/**
* validated 配置类
* @author sun
*/
@Slf4j
@Configuration
public class ValidationConfiguration {
public ValidationConfiguration(){
log.debug("创建配置类:ValidationConfiguration");
}
@Bean
public javax.validation.Validator validator(){
return Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true)//快速失败
.buildValidatorFactory()
.getValidator();
}
}
@ExceptionHandler
public JsonResult HandleBindException(BindException e){
log.debug("捕获到BindException:{}", e.getMessage());
//以下两行代码,如果有多种错误,将随机获取其中一种错误的信息,并相应
String mssage = e.getFieldError().getDefaultMessage();
return JsonResult.fail(ServiceCode.ERR_BAD_REQUEST, mssage);
/*StringBuilder stringBuilder = new StringBuilder();
List fieldErrors = e.getFieldErrors();
for(FieldError fieldError : fieldErrors){
stringBuilder.append(fieldError.getDefaultMessage());
}
return JsonResult.fail(ServiceCode.ERR_BAD_REQUEST, stringBuilder.toString());*/
}
com.google.zxing
core
3.4.1
com.google.zxing
javase
3.4.1
@Test
void contextLoads() {
String text = "https://www.baidu.com"; // 要生成二维码的文本内容
int width = 300; // 二维码图片的宽度
int height = 300; // 二维码图片的高度
String format = "png"; // 二维码图片的格式
// 设置二维码参数
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix;
try {
bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 将BitMatrix转换为BufferedImage
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
// 保存生成的二维码图片
ImageIO.write(bufferedImage, format, new File("qrcode." + format));
System.out.println("二维码生成成功!");
} catch (WriterException | IOException e) {
e.printStackTrace();
}
}
org.apache.poi
poi
4.1.2
org.apache.poi
poi-ooxml
4.1.2
com.alibaba
easyexcel
2.2.10
package com.example.erweima;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public class excel {
public static void main(String[] args) {
//二维数组
String[][] data = {
{"Name", "Age", "City"},
{"John", "25", "New York"},
{"Alice", "30", "London"}
};
String filePath = "output.xlsx";
exportToExcel(data, filePath);
System.out.println("Excel file exported successfully!");
}
public static void exportToExcel(String[][]data, String filePath){
try (Workbook workbook = new XSSFWorkbook()) {
Sheet sheet = workbook.createSheet("Sheet1");
for (int i = 0; i < data.length; i++) {
Row row = sheet.createRow(i);
for (int j = 0; j < data[i].length; j++) {
Cell cell = row.createCell(j);
cell.setCellValue(data[i][j]);
}
}
try (FileOutputStream outputStream = new FileOutputStream(filePath)) {
workbook.write(outputStream);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
org.apache.poi
poi
4.1.2
org.apache.poi
poi-ooxml
4.1.2
net.sourceforge.jexcelapi
jxl
2.6.12
package com.example.erweima;
import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelImport {
public static void main(String[] args) {
//指定路径的文件
String filePath = "D:\\project5\\erweima\\output.xlsx";
try {
FileInputStream fis = new FileInputStream(new File(filePath));
Workbook workbook = WorkbookFactory.create(fis);
Sheet sheet = workbook.getSheetAt(0); // 假设你要处理的是第一个工作表
// 遍历行
for (Row row : sheet) {
// 遍历单元格
for (Cell cell : row) {
String cellValue = "";
switch (cell.getCellType()) {
case STRING:
cellValue = cell.getStringCellValue();
break;
case NUMERIC:
cellValue = String.valueOf(cell.getNumericCellValue());
break;
// 其他类型的单元格处理方式可以根据需要添加
}
System.out.print(cellValue + " ");
}
System.out.println();
}
workbook.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}