工作中很多时候需要从Class类中获取属性的值,下面会基础获取,以及结合工作内容
java
public class Main {
public static void main(String[] args) {
Person person = new Person("张三", 25);
try {
Field nameField = Person.class.getDeclaredField("name");
Field ageField = Person.class.getDeclaredField("age");
// 设置访问权限,如果属性是私有的
nameField.setAccessible(true);
ageField.setAccessible(true);
// 获取属性值
String name = (String) nameField.get(person);
int age = (int) ageField.get(person);
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
由于业务需要得为从ftp读取到的pdf加上水印,采用itextpdf依赖的功能
xml <dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<!-- PDF文件字体 防止中文乱码 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
我是写在pdf工具类中
java public static byte[] PDFAddWatermark(byte[] pdfbyte, String waterMarkName) throws Exception {
// 每页水印行数
int row = 7;
// 每行水印个数
int col = 3;
// 旋转角度
float rotation = 30f;
byte[] decodeBuffer = pdfbyte;
// 读取PDF
PdfReader reader = new PdfReader(decodeBuffer);
//创建字节数组输出流
ByteArrayOutputStream ous =new ByteArrayOutputStream();
// 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(ous);
// 输出的PDF文件内容
PdfStamper stamper = new PdfStamper(reader, bos);
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//改透明度
gs.setStrokeOpacity(0.4f);//设置笔触字体不透明度
PdfContentByte content;
int total = reader.getNumberOfPages();//pdf文件页数
for (int i=0; i<total; i++) {
// 在内容上方加水印
content = stamper.getOverContent(i+1);
// 在内容下方加水印
// content = stamper.getUnderContent(i+1);
//开始写入
content.beginText();
content.setGState(gs);
//字体大小
content.setFontAndSize(base, 20);
//每页7行,一行3个
for (int j=0; j<col; j++) {
for (int k=0; k<row; k++) {
float x = reader.getPageSize(i+1).getWidth() / col * j + 90;
float y = reader.getPageSize(i+1).getHeight() / row * k;
//showTextAligned 方法的参数(文字对齐方式,位置内容,输出水印X轴位置,Y轴位置,旋转角度)
content.showTextAligned(Element.ALIGN_CENTER, waterMarkName, x, y, rotation);
}
}
// 添加水印文字
content.endText();
}
stamper.close();
//添加水印后pdf的base64
byte[] bytes = ous.toByteArray();
ous.close();
bos.close();
reader.close();
return bytes;
}
业务需要,得对特定的请求进行拦截,判断能不能满足状态,满足后才放行,不满足的话就抛出异常,过程主要分为四部分,首页是webMvcConfg配置,如何是拦截器的拦截逻辑编写,然后是对于json类型的消息头需要重写HttpServletRequestWrapper方法,实现多次对流的读取,不然拦截器读取后,放行请求路径对应的方法就获取不到请求体了,因为流只能读一次,所以还需要过滤器将对应的请求再塞回去
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Resource
private IRecSealService iRecSealService;
/**
* 添加拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截器,并且指定需要拦截的请求路径
registry.addInterceptor(new URLInterceptor(iRecSealService))
.addPathPatterns("/recMrIndex/aaa"
, "/recMrIndex/bbb"
, "/recMrIndex/ccc"
, "/recUpperShelf/ddd"
);
WebMvcConfigurer.super.addInterceptors(registry);
}
/**
* 对指定请求的 HttpServletRequest 进行重新注册返回
*
*/
@Bean
public FilterRegistrationBean setLogServiceFilter() {
//使用过滤器将请求体塞回去避免流只能读一次造成的错误
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
RequestBodyFilter requestBodyFilter = new RequestBodyFilter();
registrationBean.setFilter(requestBodyFilter);
registrationBean.setName("interceptor filter body params");
registrationBean.addUrlPatterns("/recMrIndex/aaa"
, "/recMrIndex/bbb"
, "/recMrIndex/ccc"
, "/recUpperShelf/ddd"
);
registrationBean.setOrder(1);
return registrationBean;
}
}
业务需要,需要设置一个拦截器,对特定接口进行校验,使用HttpServletRequest.getParameter()和getParameterMap()以及getAttribute()都获取不到请求参数,数据为空
因为是springBoot项目,参数一般都是Post方式,@RequestBody的形式,前端的配置类型是application/json,所以获取不到参数,@RequestBody是通过流的形式读取的,我们也得使用流的方式读取参数.一般使用,request.getInputStream()或者getReader()方式
request.getInputStream()或者getReader()只能调用一次,如果在拦截器层就调用了,那么@RequestBody就读取不了会出现异常信息
javaI/O error while reading input message; nested exception is java.io.IOException: Stream closed
或者
java
java.lang.IllegalStateException: getReader() has already been called for this request
由于业务需要得实现一个周期性的自动执行任务,之前的话都是在启动类上使用@EnableScheduling,然后定义一个自动任务类,在方法上使用@Scheduled(cron = "${job.archive.cron}"),来实现功能需要,这次就想换种方式实现,采用实现CommandLineRunner接口,这个接口在启动完成后,会自动执行run方法,我准备在run方法里使用周期线程池,来周期性执行。