SpringBoot与JAX-RS结合Eolink Apikit开发

开发WebService接口

导入maven

注意:cxf-spring-boot-starter-jaxrs和cxf-rt-rs-extension-providers的版本要保持一致

<?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>

    <groupId>cn.com.techfly</groupId>
    <artifactId>lzpid</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>lzpid Maven Webapp</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <!-- Spring Boot 父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.9</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- web支持,SpringMVC, Servlet支持等 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
            <version>2.7.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j</artifactId>
            <version>1.3.8.RELEASE</version>
        </dependency>
        <!-- jdbc数据库操作 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- redis操作 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.influxdb</groupId>
            <artifactId>influxdb-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!--CXF的jax-rs -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- 转换JSON插件 -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.7</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>p6spy</groupId>
            <artifactId>p6spy</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.23</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>central</id>
            <url>https://maven.aliyun.com/repository/public/</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>central</id>
            <url>https://maven.aliyun.com/repository/public/</url>
        </pluginRepository>
    </pluginRepositories>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.9</version>
                <configuration>
                    <!--				<skipTests>true</skipTests>-->
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
                <version>3.1.2</version>
            </plugin>
        </plugins>
    </build>
</project>

创建PidReport实体类

package cn.com.techfly.lzsh.bean.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PidReport {
    private int count;
    private int workid;
    private String fullname;
}

创建BaseForm实体类

package cn.com.techfly.lzsh.bean.form;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class BaseForm {
    private String apiKey;//密钥

}

创建PidReportForm实体类

package cn.com.techfly.lzsh.bean.form;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.xml.bind.annotation.XmlRootElement;

@Data
@ToString
@NoArgsConstructor
@XmlRootElement(name = "requestDatas")
public class PidReportForm extends BaseForm{
}

创建PidReportData实体类

package cn.com.techfly.lzsh.bean.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement
public class PidReportData {
    private List<PidReport> data;//数据
    private String lastTime;//更新时间
    private int status;//状态码
    private String msg;//调用接口的结果描述
}

创建接口

package cn.com.techfly.lzsh.service;

import cn.com.techfly.lzsh.bean.entity.*;
import cn.com.techfly.lzsh.bean.form.*;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

@ResponseBody
public interface IPidLoopService {
 
    /**
     *
     * @param form 请求参数
     * @return PidReportData
     */
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/pidReport")
    PidReportData getPidReportList(PidReportForm form);

实现接口

package cn.com.techfly.lzsh.util;

import cn.com.techfly.lzsh.bean.entity.*;
import cn.com.techfly.lzsh.bean.form.*;
import cn.com.techfly.lzsh.constant.StatusCode;
import cn.com.techfly.lzsh.dao.*;
import cn.com.techfly.lzsh.exception.WebServiceLzException;
import cn.com.techfly.lzsh.service.IPidLoopService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
@Service
public class PidLoopServiceImpl implements IPidLoopService {

    @Autowired
    private IPidReportDao pidReportDao;
    
    @Override
    public PidReportData getPidReportList(PidReportForm form) {
        try {
            PidReportData result = new PidReportData();
            boolean apiKey = checkApiKey(form.getApiKey());
            if (!apiKey) {
                result.setStatus(StatusCode.DENY.getValue());
                result.setMsg(StatusCode.DENY.getName());
                return result;
            }
            List<PidReport> pidReportList = pidReportDao.getPidReportList();
            //最新时间
            Timestamp lastTime = Timestamp.valueOf(LocalDateTime.now());
            //定义日期时间格式化器
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            result.setData(pidReportList);
            result.setLastTime(lastTime.toLocalDateTime().format(formatter));
            result.setStatus(StatusCode.SUCCEED.getValue());
            result.setMsg(StatusCode.SUCCEED.getName());
            return result;
        } catch (Exception e) {
            PidReportData result = new PidReportData();
            result.setStatus(StatusCode.ERROR.getValue());
            result.setMsg(StatusCode.ERROR.getName());
            String msg = "PID台账接口出错!";
            log.error(msg, e);
            throw new WebServiceLzException(msg, e);
        }
    }


    //验证apiKey
    private boolean checkApiKey(String apiKey) {
        try {
            String decrypt = RsaUtil.decrypt(apiKey);//获取apiKey
            String[] split = decrypt.split(";");//拆分apiKey数据
            String time = split[1];//获取apiKey中的时间
            LocalDateTime parse = LocalDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));//定义时间格式
            LocalDateTime now = LocalDateTime.now();//获取最新时间
            //判断大于当前时间
            //            if (parse.isAfter(now)) {
            //判断小于当前时间10分钟不满足条件
            if (parse.minusMinutes(10).isAfter(now)) {
                log.error(time);
                log.error(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                return false;
            }
            //判断大于当前时间10分钟不满足条件
            if (parse.plusMinutes(10).isBefore(now)) {
                log.error(time);
                log.error(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                return false;
            }

            return StringUtils.equals(split[0], "PIDZD@LZSH.COM");
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return false;
    }
}

创建Dao层接口

package cn.com.techfly.lzsh.dao;

import cn.com.techfly.lzsh.bean.entity.PidReport;

import java.util.List;

public interface IPidReportDao {
    List<PidReport> getPidReportList();
}

创建Dao层实现类

package cn.com.techfly.lzsh.dao.impl;

import cn.com.techfly.lzsh.annotation.DBQuery;
import cn.com.techfly.lzsh.bean.entity.PidReport;
import cn.com.techfly.lzsh.dao.IPidReportDao;
import cn.com.techfly.lzsh.util.BeanRowMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class PidReportDaoImpl implements IPidReportDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @DBQuery
    @Override
    public List<PidReport> getPidReportList() {
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT *  FROM T_LOOP_INPUT");
        List<PidReport> list = jdbcTemplate.query(sql.toString(), new BeanRowMapper<PidReport>(PidReport.class));
        return list;
    }
}

BeanRowMapper工具类

package cn.com.techfly.lzsh.util;

import cn.com.techfly.lzsh.annotation.DoubleFormat;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.core.RowMapper;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BeanRowMapper<T> implements RowMapper<T>{

	private Class<T> clazz;
	
	public BeanRowMapper(Class<T> clazz){
		this.clazz = clazz;
	}
	
	@Override
	public T mapRow(ResultSet rs, int rowNum) {
		try {
			T t = this.clazz.newInstance();
			ResultSetMetaData metaData = rs.getMetaData();
			int columnCount = metaData.getColumnCount();
			for(int i = 1; i <= columnCount; i++){
				String column = metaData.getColumnName(i);
				column = this.getColumnName(column);
				int type = metaData.getColumnType(i);
				Object value = this.parseTypeAndReturnData(rs, type, i);
				Field field = null;
				try{
					field = this.clazz.getDeclaredField(column);
				}catch(NoSuchFieldException e){}
				if(field == null){//如果在java类中没有找到数据库表字段对应的属性,直接跳过去不设置值
					continue ;
				}
				if(value != null) {
					BeanUtils.setProperty(t, column, value);
				}
				Class<?> fieldClazz = field.getType();
				//double类型的使用DoubleFormat自定义注解保留两位小数
				if(field.isAnnotationPresent(DoubleFormat.class)) {
					DoubleFormat df = field.getAnnotation(DoubleFormat.class);
					DecimalFormat format = new DecimalFormat(df.pattern());
					if(type == Types.NUMERIC) {
						if(fieldClazz == double.class || fieldClazz == Double.class) {
							if(value != null){
								Double doubleValue = Double.parseDouble(format.format((BigDecimal)value));
								BeanUtils.setProperty(t, column, doubleValue);
							}
						}
					}
					if(type == Types.DOUBLE) {
						if(fieldClazz == double.class || fieldClazz == Double.class) {
							if(value != null){
								Double doubleValue = Double.parseDouble(format.format((double)value));
								BeanUtils.setProperty(t, column, doubleValue);
							}
						}
					}
				}
			}
			return t;
		} catch (Throwable e) {
			throw new RuntimeException("ResultSet转换为Bean出错!", e);
		} 
	}
	/**
	 * user_name转成userName
	 * 数据库表字段转换成java变量
	 * @param column 数据库字段
	 * @return java类属性
	 */
	private String getColumnName(String column) {
		String name = "";
		if(!StringUtils.isBlank(column) && column.startsWith("F_")) {
			String field = column.toLowerCase().substring(2);
			Pattern pattern = Pattern.compile("[_+](.)");
			Matcher matcher = pattern.matcher(field);
			while(matcher.find()){
				int index = matcher.start();
				String value = matcher.group(1).toUpperCase();
				field = field.substring(0, index) + value + field.substring(index + 2);
				matcher = pattern.matcher(field);
			}
			name = field;
		}else {
			name = column;
		}
		return name;
	}
	
	private Object parseTypeAndReturnData(ResultSet rs, int type, int index) throws Exception{
		switch(type){
			case Types.NULL:
				return null;
			case Types.INTEGER:
				return rs.getInt(index);
			case Types.VARCHAR:
				return rs.getString(index);
			case Types.DOUBLE:
				return rs.getDouble(index);
			case Types.TIMESTAMP:
				return rs.getTimestamp(index);
			case Types.BOOLEAN:
				return rs.getBoolean(index);
			case Types.DATE:
				try {
					return rs.getDate(index);
				}catch(Exception e){
					return rs.getString(index);
				}
			case Types.NUMERIC:
				return rs.getBigDecimal(index);
			case Types.NVARCHAR:
				return rs.getString(index);
			default:
				return rs.getString(index);
		}
	}
}

DBUtil工具类

package cn.com.techfly.lzsh.util;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 新增,修改对象
 * @author sc
 *
 */
public class DBUtil {

	/**
	 * 新增对象并返回主键ID
	 * @param template
	 * @param table
	 * @param obj
	 * @return
	 */
	public static long insertReturn(JdbcTemplate template, String table, Object obj) {
		try {
			long newId = 0;
			StringBuilder buffer = new StringBuilder();
			String dbFields="";
			String positions="";//占位符
			Class clazz = obj.getClass();
			//Field[] fields = clazz.getDeclaredFields();
			Field[] fields = getPersistedField(clazz);//拿到可序列化的字段
			Object[] values = new Object[fields.length];
			for(int i = 0; i < fields.length; i++) {
				Field field = fields[i];
				field.setAccessible(true);
				String dbField = getDBFieldName(field.getName());//java变量转数据库字段
				values[i] = field.get(obj);
				if(i > 0) {
					positions += ",";
					dbFields += ",";
				}
				positions += "?";
				dbFields += dbField;
			}
			buffer.append("INSERT INTO "+table+" ("+dbFields+") VALUES ("+positions+")");
			System.out.println(buffer.toString()+"["+Arrays.toString(values)+"]");
			KeyHolder holder = new GeneratedKeyHolder();
			template.update(new MyPreparedStatementCreator(buffer.toString(), values), holder);
			newId = holder.getKey().intValue();
			return newId;
		}catch(Throwable e) {
			throw new RuntimeException("新增对象并返回主键ID出错!", e);
		}
	}
	/**
	 * 新增记录
	 * @param template
	 * @param table 表名
	 * @param obj 新增对象
	 */
	public static void insert(JdbcTemplate template, String table, Object obj) {
		try {
			StringBuilder buffer = new StringBuilder();
			String dbFields="";
			String positions="";//占位符
			Class clazz = obj.getClass();
			//Field[] fields = clazz.getDeclaredFields();
			Field[] fields = getPersistedField(clazz);//获取可序列化的字段
			Object[] values = new Object[fields.length];
			for(int i = 0; i < fields.length; i++) {
				Field field = fields[i];
				field.setAccessible(true);
				String dbField = getDBFieldName(field.getName());//java变量转数据库字段
				values[i] = field.get(obj);
				if(i > 0) {
					positions += ",";
					dbFields += ",";
				}
				positions += "?";
				dbFields += dbField;
			}
			buffer.append("INSERT INTO "+table+" ("+dbFields+") VALUES ("+positions+")");
			System.out.println(buffer.toString()+"["+Arrays.toString(values)+"]");
			template.update(buffer.toString(), values);
		}catch(Throwable e) {
			throw new RuntimeException("新增对象出错!", e);
		}
	}
	
	public static <T> void insertList(JdbcTemplate template, String table, List<T> list, Class<T> clazz) {
		try {
			StringBuilder buffer = new StringBuilder();
			String dbFields="";
			String positions="";//占位符
			//Field[] fields = clazz.getDeclaredFields();
			Field[] fields = getPersistedField(clazz);//获取可序列化的字段
			List<Object[]> valueList = new ArrayList<>();
			
			for(T t: list) {
				Object[] values = new Object[fields.length];
				for(int i = 0; i < fields.length; i++) {
					Field field = fields[i];
					field.setAccessible(true);
					values[i] = field.get(t);
				}
				valueList.add(values);
			}
			for(int i = 0; i < fields.length; i++) {
				Field field = fields[i];
				field.setAccessible(true);
				String dbField = getDBFieldName(field.getName());//java变量转数据库字段
				if(i > 0) {
					positions += ",";
					dbFields += ",";
				}
				positions += "?";
				dbFields += dbField;
			}
			buffer.append("INSERT INTO "+table+" ("+dbFields+") VALUES ("+positions+")");
			System.out.println(buffer.toString());
			template.batchUpdate(buffer.toString(), valueList);
		}catch(Throwable e) {
			throw new RuntimeException("批量新增对象出错!", e);
		}
	}
	/**
	 * 修改记录
	 * @param template
	 * @param table 表名
	 * @param obj java对象
	 * @param conditions 条件字段(不被修改)
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static void update(JdbcTemplate template, String table, Object obj, String...conditions) {
		try {
			StringBuilder buffer = new StringBuilder();
			String sql="UPDATE "+table+" SET ";
			String where = "WHERE ";
			Class clazz = obj.getClass();
			//Field[] fields = clazz.getDeclaredFields();
			Field[] fields = getPersistedField(clazz);//获取可序列化的字段
			int index1 = 0;
			Object[] values = new Object[fields.length ];
			//拼接set
			for(int i = 0; i < fields.length; i++) {
				Field field = fields[i];
				field.setAccessible(true);
				String fieldName = field.getName();
				String dbField = getDBFieldName(fieldName);//java变量转数据库字段
				boolean update = true;//是否需要更新
				for(int j = 0; j < conditions.length; j++) {
					if(conditions[j].equals(fieldName)) {
						update = false;
					}
				}
				if(update) {
					values[index1++] = field.get(obj);
					sql = sql + dbField + "=?,";
				}
			}
			sql = sql.substring(0, sql.length() - 1);
			//拼接where
			for(int i = 0; i < conditions.length; i++) {
				for(int j = 0; j < fields.length; j++) {
					Field field = fields[j];
					field.setAccessible(true);
					String fieldName = field.getName();
					String dbField = getDBFieldName(fieldName);//java变量转数据库字段
					if(conditions[i].equals(fieldName)) {
						values[index1++] = field.get(obj);
						where = where + dbField + "=? AND ";
						continue ;
					}
				}
			}
			if(where.length() > 0) {
				where = where.substring(0, where.length() - 4);
			}
			System.out.println(sql+" "+where+"["+Arrays.toString(values)+"]");
			template.update(sql+" "+where, values);
		}catch(Throwable e) {
			throw new RuntimeException("更新对象出错!", e);
		}
	}

	/**
	 * 获取可序列化的字段(没有使用org.springframework.data.annotation.Transient这个注解的字段)
	 * @param clazz
	 * @return
	 */
	private static Field[] getPersistedField(Class clazz){
		Field[] fields = clazz.getDeclaredFields();
		List<Field> list = Arrays.asList(fields);
		list = list.stream()
				   .filter(field -> !field.isAnnotationPresent(org.springframework.data.annotation.Transient.class))
				   .collect(Collectors.toList());
		return list.toArray(new Field[list.size()]);
	}
	/**
	 * userName转为F_USER_NAME
	 * java对象字段转数据库表字段
	 * @param field
	 * @return
	 */
	private static String getDBFieldName(String field) {
		String dbField = "F_"+field.substring(0, 1);
		String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		String lower = upper.toLowerCase();
		for(int i = 1; i < field.length(); i++) {
			String s = String.valueOf(field.charAt(i));
			if(upper.contains(s)) {//大写字母
				dbField = dbField + "_" + s;
			}else if(lower.contains(s)) {//小写字母
				dbField = dbField +  s;
			}else {//数字或下划线
				dbField = dbField +  s;
			}
		}
		return dbField.toUpperCase();
	}
	
	/*public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
		EditDepartmentForm add = new EditDepartmentForm();
		add.setFullName("测试");
		//add.setParentId(0);
		add.setChangeTime(new Timestamp(new Date().getTime()));
		add.setChangeUser(2);
		add.setEngName("TEST");
		add.setSort(1);
		update(null, "T_DEPARTMENT", add, "id");
		System.out.println(NumberUtils.isNumber("00.99"));
	}*/
}

MyPreparedStatementCreator工具类

package cn.com.techfly.lzsh.util;

import org.springframework.jdbc.core.PreparedStatementCreator;

import java.sql.*;

public class MyPreparedStatementCreator implements PreparedStatementCreator{

	private String sql;
	private Object[] params;
	
	public MyPreparedStatementCreator(String sql, Object...params){
		this.sql = sql;
		this.params = params;
	}
	@Override
	public PreparedStatement createPreparedStatement(Connection conn)
			throws SQLException {
		PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
		try{
			this.parseParams(ps, params);
			return ps;
		}catch(Exception e){
			throw new RuntimeException("解析SQL语句参数出错!", e);
		}
	}

	private void parseParams(PreparedStatement statement, Object...obj) throws Exception{
		for(int i = 0; i < obj.length; i++){
			Object param = obj[i];
			if(param == null){
				statement.setNull(i + 1, Types.NULL);
			}else if(param instanceof Integer){
				statement.setInt(i + 1, (Integer)param);
			}else if(param instanceof String){
				statement.setString(i + 1, (String)param);
			}else if(param instanceof Double){
				statement.setDouble(i + 1, (Double)param);
			}else if(param instanceof Long){
				statement.setLong(i + 1, (Long)param);
			}else if(param instanceof Timestamp){
				statement.setTimestamp(i + 1, (Timestamp)param);
			}else if(param instanceof Boolean){
				statement.setBoolean(i + 1, (Boolean)param);
			}else if(param instanceof Date){
				statement.setDate(i + 1, new Date(((Date) param).getTime()));
			}else{
				statement.setString(i + 1, (String)param);
			}
		}
	}
}

编写获取Redis数据工具类

package cn.com.techfly.lzsh.util;

import cn.com.techfly.lzsh.config.SpringBeanUtil;
import cn.com.techfly.lzsh.influxDB.HisData;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

public class Redis0Util {

    private static final String LOOP_CALC_TIME = "LoopCalcTime";
    private static final String STATIONARY_TIME = "StationaryTime";
    private static final String F_TIME = "F_TIME";
    private static final String redis = "redis";

    /**
     * 获取回路计算时间
     *
     * @return 字符串
     */
    public static String getLoopCalcTime() {
        Optional<StringRedisTemplate> optional = SpringBeanUtil.getBean(redis, StringRedisTemplate.class);
        if (!optional.isPresent()) {
            return "";
        }
        StringRedisTemplate redisTemplate = optional.get();
        String loopCalcTime = redisTemplate.opsForValue().get(LOOP_CALC_TIME);
        if (!StringUtils.isBlank(loopCalcTime)) {
            loopCalcTime = loopCalcTime.replace("_", " ");
        }
        return loopCalcTime;
    }

    /**
     * 获取StationaryTime
     *
     * @return 字符串
     */
    public static String getStationaryTime() {
        Optional<StringRedisTemplate> optional = SpringBeanUtil.getBean(redis, StringRedisTemplate.class);
        if (!optional.isPresent()) {
            return "";
        }
        StringRedisTemplate redisTemplate = optional.get();
        String stationaryTime = redisTemplate.opsForValue().get(STATIONARY_TIME);
        if (!StringUtils.isBlank(stationaryTime)) {
            stationaryTime = stationaryTime.replace("_", " ");
        }
        return stationaryTime;
    }

    /**
     * 获取F_TIME的值
     *
     * @return
     */
    public static String getTime() {
        Optional<StringRedisTemplate> optional = SpringBeanUtil.getBean(redis, StringRedisTemplate.class);
        if (!optional.isPresent()) {
            return "";
        }
        StringRedisTemplate redisTemplate = optional.get();
        String time = redisTemplate.opsForValue().get(F_TIME);
        if (!StringUtils.isBlank(time)) {
            time = time.replace("_", " ");
        }
        return time;
    }

    public static List<HisData> getHisDataList(String dpids) {
        List<String> dpIdList = new ArrayList<>();
        if (!StringUtils.isBlank(dpids)) {
            dpIdList = Arrays.asList(dpids.split(","));
        }
        List<HisData> list = new ArrayList<>();
        Optional<StringRedisTemplate> optional = SpringBeanUtil.getBean(redis, StringRedisTemplate.class);
        if (!optional.isPresent()) {
            return list;
        }
        StringRedisTemplate redisTemplate = optional.get();
        Set<String> sets = redisTemplate.keys("*");
        if (sets != null && sets.size() > 0 && sets.contains(F_TIME)) {
            String timeValue = redisTemplate.opsForValue().get(F_TIME);
            for (String key : sets) {
                String value = redisTemplate.opsForValue().get(key);
                if (F_TIME.equals(key) || LOOP_CALC_TIME.equals(key)) {
                    continue;
                }
                if (value != null && value.contains(",")) {
                    HisData hisData = new HisData(key, timeValue, value, list.size());
                    if (dpIdList.size() > 0 && dpIdList.contains(String.valueOf(hisData.getDpId()))) {
                        list.add(hisData);
                    }
                    if (dpIdList.size() == 0) {
                        list.add(hisData);
                    }
                }
            }
        }
        return list;
    }

    public static List<String> getDpidList() {
        List<String> list = new ArrayList<>();
        Optional<StringRedisTemplate> optional = SpringBeanUtil.getBean(redis, StringRedisTemplate.class);
        if (!optional.isPresent()) {
            return list;
        }
        StringRedisTemplate redisTemplate = optional.get();
        Set<String> sets = redisTemplate.keys("*[,]*");
        if (sets != null && sets.size() > 0) {
            List<String> tempList = sets.stream().collect(Collectors.toList());
            for (String str : tempList) {
                String dpid = str.substring(0, str.indexOf(","));
                if (!list.contains(dpid)) {
                    list.add(dpid);
                }
            }
        }
        return list;
    }
}

利用RSA编写apiKey解密类

package cn.com.techfly.lzsh.util;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;


public class RsaUtil {

    //私钥
    private static final String privateKey = "私钥";

    /**
     * 解密方法
     */
    public static String decrypt(String s1) {
        RSA rsa2 = new RSA(privateKey, null);
        String s2 = rsa2.decryptStr(s1, KeyType.PrivateKey);
        return s2;
    }

}

编写application-dev.properties.yml配置工具

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://127.0.0.1:1433;DatabaseName=数据库名;encrypt=true;trustServerCertificate=true
spring.datasource.username=账号
spring.datasource.password=密码
###connection pool
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
##ms
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
##spring.datasource.filters=stat,wall,log4j
spring.datasource.filters=stat,log4j
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=200
spring.datasource.logSlowSql=true
## redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
spring.redis.pool.max-active=100
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=60000

编写application.properties.yml配置文件

server.port=8088
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
spring.mvc.static-path-pattern=/static/**
spring.profiles.active=dev
spring.http.multipart.enabled=false
spring.servlet.multipart.enabled=false
application.version=20240129

配置Druid数据源

package cn.com.techfly.lzsh.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DruidConfig {

    @Value("${spring.datasource.url}")  
    private String url;  
    @Value("${spring.datasource.username}")  
    private String username;  
    @Value("${spring.datasource.password}")  
    private String password;  
    @Value("${spring.datasource.driver-class-name}")  
    private String driverClassName;  
    @Value("${spring.datasource.initial-size}")  
    private int initialSize;//初始化时建立物理连接的个数  
    @Value("${spring.datasource.min-idle}")  
    private int minIdle;//最小连接数量  
    @Value("${spring.datasource.max-active}")  
    private int maxActive;//最大连接数量  
    @Value("${spring.datasource.max-wait}")  
    private int maxWait;//获取连接时最大等待时间,单位毫秒  
    @Value("${spring.datasource.time-between-eviction-runs-millis}")  
    private int timeBetweenEvictionRunsMillis;//配置隔多久进行一次检测(检测可以关闭的空闲连接)  
    @Value("${spring.datasource.min-evictable-idle-time-millis}")  
    private int minEvictableIdleTimeMillis;//配置连接在池中的最小生存时间  
    @Value("${spring.datasource.validation-query}")  
    private String validationQuery;//用来检测连接是否有效的sql,要求是一个查询语句  
    @Value("${spring.datasource.test-while-idle}")  
    private boolean testWhileIdle;//建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效  
    @Value("${spring.datasource.test-on-borrow}")  
    private boolean testOnBorrow;//申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能  
    @Value("${spring.datasource.test-on-return}")  
    private boolean testOnReturn;//归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能  
    @Value("${spring.datasource.pool-prepared-statements}")  
    private boolean poolPreparedStatements;//是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。  
    @Value("${spring.datasource.max-pool-prepared-statement-per-connection-size}")  
    private int maxPoolPreparedStatementPerConnectionSize;//指定每个连接上PSCache的大小  
    /**
     * 配置DataSouurce
     * @return
     */
    @Bean
    public DataSource duridDataSource(){
    	try{
    		DruidDataSource datasource = new DruidDataSource();  
            datasource.setUrl(url);  
            datasource.setUsername(username);  
            datasource.setPassword(password);  
            datasource.setDriverClassName(driverClassName);  
            datasource.setInitialSize(initialSize);  
            datasource.setMinIdle(minIdle);  
            datasource.setMaxActive(maxActive);  
            datasource.setMaxWait(maxWait);  
            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
            datasource.setValidationQuery(validationQuery);  
            datasource.setTestWhileIdle(testWhileIdle);  
            datasource.setTestOnBorrow(testOnBorrow);  
            datasource.setTestOnReturn(testOnReturn);  
            datasource.setPoolPreparedStatements(poolPreparedStatements);  
            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);  
            return datasource; 
    	}catch(Exception e){
    		throw new RuntimeException("初始化Durid连接池出错!", e);
    	}  
    }
}

配置redis

package cn.com.techfly.lzsh.config;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisConfig {

	@Value("${spring.redis.host}") 
	private String host;
	@Value("${spring.redis.port}") 
	private int port;
	@Value("${spring.redis.password}") 
	private String password;
	@Value("${spring.redis.database}") 
	private int database;
	@Value("${spring.redis.pool.max-active}")
	private int maxActive;
	@Value("${spring.redis.pool.max-wait}")
	private int maxWait;
	@Value("${spring.redis.pool.max-idle}")
	private int maxIdle;
	@Value("${spring.redis.pool.min-idle}")
	private int minIdle;
	@Value("${spring.redis.timeout}")
	private int timeout;
	
	@Bean("redis")
	public StringRedisTemplate stringRedisTemplate(){
		RedisConnectionFactory cf = this.getRedisConnectionFactory(0);
		return new StringRedisTemplate(cf);
	}
	
	@Bean("redis1")
	public StringRedisTemplate stringRedisTemplate1(){
		RedisConnectionFactory cf = this.getRedisConnectionFactory(1);
		return new StringRedisTemplate(cf);
	}
	
	@Bean("redis2")
	public StringRedisTemplate stringRedisTemplate2(){
		RedisConnectionFactory cf = this.getRedisConnectionFactory(2);
		return new StringRedisTemplate(cf);
	}
	
	@SuppressWarnings("deprecation")
	private RedisConnectionFactory getRedisConnectionFactory(int dbNum) {
		JedisConnectionFactory jedisFactory = new JedisConnectionFactory();
        jedisFactory.setHostName(host);
        jedisFactory.setPort(port);
        if(!StringUtils.isBlank(password)) {
        	jedisFactory.setPassword(password);
        }
        jedisFactory.setDatabase(dbNum);
        jedisFactory.setTimeout(timeout);
        JedisPoolConfig poolConfig = new JedisPoolConfig(); // 进行连接池配置
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWait);
        jedisFactory.setPoolConfig(poolConfig);
        jedisFactory.afterPropertiesSet(); // 初始化连接池配置
        return jedisFactory;
	}
}

配置spring工具类

package cn.com.techfly.lzsh.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class SpringBeanUtil implements ApplicationContextAware{
    
    private static ApplicationContext applicationContext;
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		if(SpringBeanUtil.applicationContext == null) {
			SpringBeanUtil.applicationContext = applicationContext;
        }
		System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringBeanUtil.applicationContext+"========");
	}

	//获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Optional<Object> getBean(String name){
	    Optional<Object> optional = Optional.empty();
	    try{
            Object bean = getApplicationContext().getBean(name);
            optional = Optional.of(bean);
        }catch (Exception e){}
        return optional;
    }
    //检查bean是否已经存在
    public static boolean existBean(String name){
        return applicationContext.containsBean(name);
    }
    //通过class获取Bean.
    public static <T> Optional<T> getBean(Class<T> clazz){
        Optional optional = Optional.empty();
	    try {
            T bean = getApplicationContext().getBean(clazz);
            optional = Optional.of(bean);
        }catch (Exception e){}
        return optional;
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> Optional<T> getBean(String name, Class<T> clazz){
        Optional<T> optional = Optional.empty();
        try{
            T bean = getApplicationContext().getBean(name, clazz);
            optional = Optional.of(bean);
        }catch (Exception e){}
        return optional;
    }
    //注入并返回Bean
    public static <T> T registerBean(String name, Class<T> clazz, Object... args) {
    	ConfigurableApplicationContext cApplicationContext = (ConfigurableApplicationContext)getApplicationContext();
    	if(applicationContext.containsBean(name)) {
            T bean = cApplicationContext.getBean(name, clazz);
            if (bean.getClass().isAssignableFrom(clazz)) {
                return bean;
            } else {
                throw new RuntimeException("BeanName 重复 " + name);
            }
        }
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        for (Object arg : args) {
            beanDefinitionBuilder.addConstructorArgValue(arg);
        }
        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();

        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) cApplicationContext.getBeanFactory();
        beanFactory.registerBeanDefinition(name, beanDefinition);
        return cApplicationContext.getBean(name, clazz);
    }
    //删除bean
    public static void removeBean(String name){
        ConfigurableApplicationContext cApplicationContext = (ConfigurableApplicationContext)getApplicationContext();
        if(applicationContext.containsBean(name)) {
            BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) cApplicationContext.getBeanFactory();
            beanFactory.removeBeanDefinition(name);
        }
    }
}

配置WebServiceConfig类

package cn.com.techfly.lzsh.config;

import cn.com.techfly.lzsh.service.IPidLoopService;
import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebServiceConfig {
    @Autowired
    private Bus bus;

    @Autowired
    private IPidLoopService pidLoopService;

    @Bean(name="rsServletRegistrationBean")
    public ServletRegistrationBean getRegistrationBean(){
        return new ServletRegistrationBean(new CXFServlet(), "/webapi/*");
    }

    @Bean
    public Server createServer(){
        JAXRSServerFactoryBean endpoint= new JAXRSServerFactoryBean();
        //设置参数
        //设置访问地址
        endpoint.setAddress("/pidzd");
        //设置bus
        endpoint.setBus(bus);
        //设置实体类对象
        endpoint.setServiceBean(pidLoopService);
        return endpoint.create();
    }
}

创建SpringBoot启动类

package cn.com.techfly.lzsh;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class LzPidWebServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(LzPidWebServiceApplication.class,args);
    }
}

运行程序

成功运行服务端代码
成功运行服务端代码。

使用Eolink Apikit工具访问接口

在左侧选择快速测试左侧选择快速测试

请求地址

请求地址

请求头

请求头

请求体

请求体

请求结果示例

请求结果示例

  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以按照以下步骤将JAX-WS接口替换为JAX-RS接口: 1. 创建JAX-RS接口:创建一个新的Java接口来定义您的JAX-RS服务。在接口上使用`@Path`注解指定资源的URL路径。 ```java import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/your-resource") public interface YourResource { @GET @Produces(MediaType.APPLICATION_JSON) String getResource(); } ``` 2. 实现JAX-RS接口:创建一个类来实现您的JAX-RS接口,并实现接口中定义的方法。 ```java public class YourResourceImpl implements YourResource { @Override public String getResource() { // 实现您的业务逻辑 return "Hello JAX-RS!"; } } ``` 3. 注册JAX-RS服务:将您的JAX-RS服务注册到应用程序中。这可以通过创建一个`javax.ws.rs.core.Application`子类并在其中注册资源类来完成。 ```java import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import java.util.HashSet; import java.util.Set; @ApplicationPath("/api") public class YourApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(); classes.add(YourResourceImpl.class); return classes; } } ``` 4. 配置JAX-RS:根据您使用的应用程序服务器,将JAX-RS的实现(如Jersey或RestEasy)添加到您的应用程序的构建配置文件中。您还需要确保在应用程序服务器上正确配置JAX-RS。 5. 测试JAX-RS接口:启动您的应用程序服务器,并使用JAX-RS客户端或浏览器等工具测试您的JAX-RS接口。 请注意,以上步骤是一般的指导,具体步骤可能因您使用的框架和工具而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值