Commit 313c45c3 authored by 位宇华's avatar 位宇华

代码提交

parents
Pipeline #9 failed with stages
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.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 http://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.4.5</version>
<relativePath/>
</parent>
<groupId>com.tianyi</groupId>
<artifactId>ofd-service</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.31</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.21</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.ofdrw</groupId>
<artifactId>ofdrw-converter</artifactId>
<version>2.2.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- mysql的依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
<scope>runtime</scope>
</dependency>
<!-- JDBC启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.7.18</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--如果是打jar包,则需在build的plugins中添加如下配置-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--值为true是指打包时包含scope为system的第三方Jar包-->
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.tianyi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@MapperScan(basePackages = {"com.tianyi.mapper"})
public class OfdApplication {
public static void main(String[] args) {
SpringApplication.run(OfdApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner() {
return args -> System.err.println("ofd转换系统启动!");
}
}
\ No newline at end of file
package com.tianyi.common;
import java.io.Serializable;
/**
* @Author jiuli
* @Date 2024/2/22
*/
public class BaseResponse<T> implements Serializable {
private static final long serialVersionUID = -2243004256529006189L;
private int code;
private T data;
private String message;
public BaseResponse(int code, T data, String message) {
this.code = code;
this.data = data;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package com.tianyi.common;
/**
* @Author jiuli
* @Date 2024/2/22
*/
public enum ErrorCode {
SUCCESS(0, "ok", ""),
PARAM_ERROR(40000, "请求参数错误", ""),
NULL_ERROR(40001, "数据为空", ""),
NULL_AUTH(40101, "无权限", ""),
NOT_LOGIN(40100, "未登录", ""),
SYSTEM_ERROR(50000, "系统内部异常", ""),
KEY_REPEAT(500,"请求参数错误","该企业已拥有密钥,不可重复生成!");
private final int code;
/**
* 状态码信息
*/
private final String message;
/**
* 状态码详情
*/
private final String description;
ErrorCode(int code, String message, String description) {
this.code = code;
this.message = message;
this.description = description;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public String getDescription() {
return description;
}
}
package com.tianyi.config;
import com.tianyi.interceptor.SignInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
private final SignInterceptor signInterceptor;
public WebMvcConfig(SignInterceptor signInterceptor) {
this.signInterceptor = signInterceptor;
}
/**
* WebMvc配置
* @param registry
*/
public void addInterceptors(InterceptorRegistry registry) {
//不拦截的地址
List<String> excludeUrlList = new ArrayList<>();
excludeUrlList.add("/swagger-ui.html");
excludeUrlList.add("/swagger-ui.html/**");
excludeUrlList.add("/webjars/**");
excludeUrlList.add("/swagger/**");
excludeUrlList.add("/doc.html");
excludeUrlList.add("/doc.html/**");
excludeUrlList.add("/swagger-resources/**");
excludeUrlList.add("/v2/**");
excludeUrlList.add("/favicon.ico");
//生成应用id和密钥接口不拦截
excludeUrlList.add("/secret");
registry.addInterceptor(signInterceptor)
//拦截所有请求
.addPathPatterns("/**")
//排除的请求
.excludePathPatterns(excludeUrlList);
super.addInterceptors(registry);
}
}
package com.tianyi.controller;
import com.tianyi.common.BaseResponse;
import com.tianyi.common.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @Author jiuli
* @Date 2024/2/22
*/
@RestControllerAdvice("com.tianyi")
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public <T>BaseResponse<T> runtimeException(RuntimeException e) {
log.error("RuntimeException:{}", e.getMessage(), e);
return new BaseResponse<>(ErrorCode.KEY_REPEAT.getCode(),null, e.getMessage());
}
}
package com.tianyi.controller;
import com.tianyi.model.RequestModel;
import com.tianyi.service.PdfToOfdService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PdfToOfdController {
private final PdfToOfdService pdfToOfdService;
public PdfToOfdController(PdfToOfdService pdfToOfdService) {
this.pdfToOfdService = pdfToOfdService;
}
/**
* pdf转ofd
*
* @param requestModel
* @return
*/
@PostMapping("/pdf/convert")
public Object pdfToOfd(@RequestBody RequestModel requestModel) {
return pdfToOfdService.convert(requestModel);
}
}
package com.tianyi.controller;
import com.tianyi.service.SecretService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SecretController {
private final SecretService secretService;
public SecretController(SecretService secretService) {
this.secretService = secretService;
}
/**
* 生成应用id和密钥
*
* @param org
* @return
*/
@GetMapping("/secret")
public Object getSecret(@RequestParam("org") String org) {
return secretService.getSecret(org);
}
}
package com.tianyi.interceptor;
import com.tianyi.mapper.SecretMapper;
import com.tianyi.sign.Signature;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@Component
public class SignInterceptor implements HandlerInterceptor {
private final SecretMapper secretMapper;
public SignInterceptor(SecretMapper secretMapper) {
this.secretMapper = secretMapper;
}
@SneakyThrows
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//分配的应用id
String appId = request.getHeader("appId");
//时间戳
String timestampStr = request.getHeader("timestamp");
//签名
String signature = request.getHeader("signature");
if (StringUtils.isBlank(appId) || StringUtils.isBlank(timestampStr) || StringUtils.isBlank(signature)) {
response.setStatus(500);
response.getWriter().println("参数错误!");
return false;
}
//这个密钥实际应该根据appId到数据库里查出来
String appSecret = secretMapper.getAppSecret(appId);
//如果密钥没查到
if (StringUtils.isBlank(appSecret)) {
response.setStatus(500);
response.getWriter().println("密钥不存在,请联系平台进行授权!");
}
//拼接数据
String origin = appId + appSecret + timestampStr;
if (!Signature.verify(appSecret, origin, signature)) {
response.setStatus(500);
response.getWriter().println("签名错误!");
return false;
}
//业务的时间戳
long timestamp = Long.parseLong(timestampStr);
//当前时间戳
long currentTimestamp = System.currentTimeMillis() / 1000;
//10分钟内有效
long timeDifference = 10 * 60;
if (Math.abs(timestamp - currentTimestamp) < timeDifference) {
response.setStatus(500);
response.getWriter().println("签名过期!");
return false;
}
//放行
return true;
}
}
package com.tianyi.mapper;
import com.tianyi.model.SecretModel;
import org.apache.ibatis.annotations.Param;
public interface SecretMapper {
void insert(SecretModel secretModel);
int getCount(@Param("org") String org);
String getAppSecret(@Param("appId") String appId);
}
package com.tianyi.model;
import java.io.Serializable;
public class RequestModel implements Serializable {
private String urlStr;
public String getUrlStr() {
return urlStr;
}
public void setUrlStr(String urlStr) {
this.urlStr = urlStr;
}
}
package com.tianyi.model;
import java.io.Serializable;
public class SecretModel implements Serializable {
private String appId;
private String appSecret;
private String org;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
public String getOrg() {
return org;
}
public void setOrg(String org) {
this.org = org;
}
}
package com.tianyi.service;
import com.tianyi.model.RequestModel;
public interface PdfToOfdService {
Object convert(RequestModel requestModel);
}
package com.tianyi.service;
public interface SecretService {
Object getSecret(String org);
}
package com.tianyi.service.impl;
import com.tianyi.model.RequestModel;
import com.tianyi.service.PdfToOfdService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.ofdrw.graphics2d.OFDGraphicsDocument;
import org.ofdrw.graphics2d.OFDPageGraphics2D;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Service
public class PdfToOfdServiceImpl implements PdfToOfdService {
private static final Logger log = LoggerFactory.getLogger(PdfToOfdServiceImpl.class);
@Override
@SneakyThrows
public Object convert(RequestModel requestModel) {
URL url = new URL(requestModel.getUrlStr());
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (OFDGraphicsDocument ofdDoc = new OFDGraphicsDocument(outputStream); PDDocument pdfDoc = PDDocument.load(inputStream)) {
PDFRenderer pdfRender = new PDFRenderer(pdfDoc);
for (int pageIndex = 0; pageIndex < pdfDoc.getNumberOfPages(); pageIndex++) {
PDRectangle pdfPageSize = pdfDoc.getPage(pageIndex).getBBox();
OFDPageGraphics2D ofdPageG2d = ofdDoc.newPage(pdfPageSize.getWidth(), pdfPageSize.getHeight());
pdfRender.renderPageToGraphics(pageIndex, ofdPageG2d);
}
}
Path out = null;
String os=System.getProperty("os.name").toLowerCase();
log.error("系统类别:{}",os);
if (StringUtils.contains(os,"linux")){
out=Paths.get("/home/ofd/ofddir/"+System.currentTimeMillis() + ".ofd");
}
if (StringUtils.contains(os,"windows")){
out = Paths.get("target", System.currentTimeMillis() + ".ofd");
Files.write(out, outputStream.toByteArray());
}
assert out != null;
URI uri=out.toUri();
return uri.getPath();
}
}
package com.tianyi.service.impl;
import com.tianyi.mapper.SecretMapper;
import com.tianyi.model.SecretModel;
import com.tianyi.service.SecretService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.UUID;
@Service
public class SecretServiceImpl implements SecretService {
private final SecretMapper secretMapper;
public SecretServiceImpl(SecretMapper secretMapper) {
this.secretMapper = secretMapper;
}
@Override
public Object getSecret(String org) {
String appId = (StringUtils.replace(UUID.randomUUID().toString(), "-", "")).toLowerCase();
String appSecret = UUID.randomUUID().toString().toUpperCase();
SecretModel secretModel = new SecretModel();
secretModel.setAppId(appId);
secretModel.setAppSecret(appSecret);
secretModel.setOrg(org);
int count=secretMapper.getCount(org);
if (count!=0){
throw new RuntimeException("该企业已拥有密钥,不可重复生成!");
}
secretMapper.insert(secretModel);
return secretModel;
}
}
package com.tianyi.sign;
import lombok.SneakyThrows;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Signature {
/**
* 获取签名
*
* @param secretKey
* @param data
* @return
*/
@SneakyThrows
public static String signWithHmacSha1(String secretKey, String data) {
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
}
/**
* 验证签名
*
* @param secretKey
* @param data
* @param hmac
* @return
*/
public static boolean verify(String secretKey, String data, String hmac) {
String calculatedHmac = signWithHmacSha1(secretKey, data);
return calculatedHmac.equals(hmac);
}
}
package com.tianyi.utils;
import com.tianyi.common.BaseResponse;
/**
* @Author jiuli
* @Date 2024/2/22
* 减少重复new BaseResponse 返回类,使代码更加简洁
*/
public class ResultUtils {
/**
* 成功
*
* @param data
* @param <T>
* @return
*/
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<T>(0, data, "ok");
}
}
server:
port: 8848
servlet:
# 应用的访问路径2
context-path: /ofd
spring:
#数据源配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.111.226:3306/ofd-service?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
mybatis:
mapper-locations: classpath*:mapper/*Mapper.xml
\ No newline at end of file
${AnsiColor.BRIGHT_YELLOW}
* __----~~~~~~~~~~~------___
* . . ~~//====...... __--~ ~~
* -. \_|// |||\\ ~~~~~~::::... /~
* ___-==_ _-~o~ \/ ||| \\ _/~~-
* __---~~~.==~||\=_ -_--~/_-~|- |\\ \\ _/~
* _-~~ .=~ | \\-_ '-~7 /- / || \ /
* .~ .~ | \\ -_ / /- / || \ /
* / ____ / | \\ ~-_/ /|- _/ .|| \ /
* |~~ ~~|--~~~~--_ \ ~==-/ | \~--===~~ .\
* ' ~-| /| |-~\~~ __--~~
* |-~~-_/ | | ~\_ _-~ /\
* / \ \__ \/~ \__
* _--~ _/ | .-~~____--~-/ ~~==.
* ((->/~ '.|||' -_| ~~-/ , . _||
* -_ ~\ ~~---l__i__i__i--~~_/
* _-~-__ ~) \--______________--~~
* //.-~~~-~_--~- |-------~~~~~~~~
* //.-~~~--\
* 神兽保佑
* 代码无BUG!
${AnsiColor.BRIGHT_RED}
Project (version): Spring-Boot ${spring-boot.version}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tianyi.mapper.SecretMapper">
<insert id="insert">
INSERT INTO ofd_api (app_id, app_secret, org)
values (#{appId}, #{appSecret}, #{org})
</insert>
<select id="getCount" resultType="java.lang.Integer">
select count(org)
from ofd_api
where org = #{org}
</select>
<select id="getAppSecret" resultType="java.lang.String">
select app_secret
from ofd_api
</select>
</mapper>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment