feat(Java_SpringExample): 优化类名、@auther、添加控制层测试
CacheController 缓存
EncodedController 编码
FreemarkerController 模板
FullFillTimeValueController 补时间
ITextController pdf生成
LoginController 登录控制
RedisController redis操作
RequestLimitController 接口访问频率控制
WangEditorController WangEditor编辑器使用
This commit is contained in:
@@ -9,3 +9,16 @@
|
||||
新增上下文刷新判断处理类(refreshEvent)、添加HttpSession监听器(listener)
|
||||
|
||||
2020/6/3 :增加Servlet监听器启动Schedule定时任务(SchemeTaskListener)
|
||||
|
||||
2020/6/30 : 新增WangEditor使用示例
|
||||
|
||||
2020/6/30 :优化类名、@auther、添加控制层测试
|
||||
CacheController 缓存
|
||||
EncodedController 编码
|
||||
FreemarkerController 模板
|
||||
FullFillTimeValueController 补时间
|
||||
ITextController pdf生成
|
||||
LoginController 登录控制
|
||||
RedisController redis操作
|
||||
RequestLimitController 接口访问频率控制
|
||||
WangEditorController WangEditor编辑器使用
|
||||
@@ -10,11 +10,11 @@ import org.aspectj.lang.annotation.*;
|
||||
*/
|
||||
@Aspect
|
||||
public class AopTestClass {
|
||||
@Before("execution(* service.MainServiceImpl.*(..))")
|
||||
@Before("execution(* service.CommonServiceImpl.*(..))")
|
||||
public void begin(){
|
||||
System.out.println("表演开始");
|
||||
}
|
||||
@After("execution(* service.MainServiceImpl.*(..))")
|
||||
@After("execution(* service.CommonServiceImpl.*(..))")
|
||||
public void end(){
|
||||
System.out.println("表演结束");
|
||||
}
|
||||
@@ -23,11 +23,11 @@ public class AopTestClass {
|
||||
* 通过这个声明来实现环绕通知,所谓的环绕通知就是说在在一个方法中规定了类运行几个状态直接的通知事件
|
||||
* 可以这样声明来实现不用写一大串的代码
|
||||
*/
|
||||
@Pointcut("execution(* service.MainServiceImpl.*(..))")
|
||||
@Pointcut("execution(* service.CommonServiceImpl.*(..))")
|
||||
public void perform(){}
|
||||
|
||||
@Around("perform()")
|
||||
public void AroundAop(ProceedingJoinPoint proceedingJoinPoint){
|
||||
public Object aroundAop(ProceedingJoinPoint proceedingJoinPoint){
|
||||
try{
|
||||
System.out.println("我在程序运行之前进行了通知");
|
||||
//这个方法代表被切接口进行执行,上面的方法表示之前执行,下面的方法表示之后执行
|
||||
@@ -37,17 +37,18 @@ public class AopTestClass {
|
||||
throwable.printStackTrace();
|
||||
System.out.println("运行错误产生的aop通知");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个是测试有传参的Aop接口环绕
|
||||
* @param testNum 入参,根据方法决定入参的数量与类型
|
||||
*/
|
||||
@Pointcut("execution(* service.MainServiceImpl.testAopParam(int)) && args(testNum)")
|
||||
@Pointcut("execution(* service.CommonServiceImpl.testAopParam(int)) && args(testNum)")
|
||||
public void testAopParams(int testNum){
|
||||
}
|
||||
|
||||
@After("testAopParams(testNum)")
|
||||
@After(value = "testAopParams(testNum)", argNames = "testNum")
|
||||
public void testHasParam(int testNum){
|
||||
System.out.println(testNum);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ public class SensitiveAop {
|
||||
*/
|
||||
@Around("execution(* controller.*.*(..)) && @annotation(sensitive)")
|
||||
public Object getClassMessage(ProceedingJoinPoint pjp, Sensitive sensitive) {
|
||||
|
||||
//todo 这边需要怎么去处理,我还没想清楚
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,19 +36,23 @@ import java.lang.reflect.InvocationTargetException;
|
||||
*/
|
||||
public class FreeMarkerConfigurationAdapter {
|
||||
|
||||
//配置器的类路径
|
||||
/**
|
||||
* 配置器的类路径
|
||||
*/
|
||||
private String filePath;
|
||||
//默认路径配置
|
||||
private final String defaultPath = "tpl";
|
||||
|
||||
//编码配置
|
||||
/**
|
||||
* 编码配置
|
||||
*/
|
||||
private String encoding;
|
||||
//默认编码配置
|
||||
private final String defaultEncoding = "UTF-8";
|
||||
|
||||
//错误解决类配置
|
||||
/**
|
||||
* 错误解决类配置
|
||||
*/
|
||||
private TemplateExceptionHandler exceptionHandler;
|
||||
//默认错误解决类配置
|
||||
/**
|
||||
* 默认错误解决类配置
|
||||
*/
|
||||
private final TemplateExceptionHandler defaultExceptionHandler = TemplateExceptionHandler.RETHROW_HANDLER;
|
||||
|
||||
public FreeMarkerConfigurationAdapter() {
|
||||
@@ -64,25 +68,21 @@ public class FreeMarkerConfigurationAdapter {
|
||||
*
|
||||
* 我们使用反射的机制,构造有参数的构造器,作为一个适配器,接受生成继承Configuration的子类对象<br><br>
|
||||
* 这里使用了反射的机制,可以了解一下
|
||||
* @param clazz
|
||||
* @param <T>
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InstantiationException
|
||||
* @throws NoSuchMethodException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Configuration> T createConfiguration(Class<T> clazz) throws IOException, IllegalAccessException,
|
||||
InstantiationException, NoSuchMethodException, InvocationTargetException {
|
||||
Constructor constructor = clazz.getDeclaredConstructor(new Class[]{Version.class});
|
||||
constructor.setAccessible(true); //设置语法检查?
|
||||
Constructor constructor = clazz.getDeclaredConstructor(Version.class);
|
||||
//设置语法检查?
|
||||
constructor.setAccessible(true);
|
||||
T t = (T) constructor.newInstance(Configuration.VERSION_2_3_22);
|
||||
|
||||
|
||||
// Configuration configuration = new Configuration(Configuration.VERSION_2_3_22);
|
||||
//默认路径配置
|
||||
String defaultPath = "tpl";
|
||||
Resource resource1 = new ClassPathResource(defaultPath);
|
||||
t.setDirectoryForTemplateLoading(resource1.getFile());
|
||||
//默认编码配置
|
||||
String defaultEncoding = "UTF-8";
|
||||
t.setDefaultEncoding(defaultEncoding);
|
||||
t.setTemplateExceptionHandler(defaultExceptionHandler);
|
||||
if (StringUtils.isNotEmpty(filePath)) {
|
||||
@@ -98,16 +98,4 @@ public class FreeMarkerConfigurationAdapter {
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public void setExceptionHandler(TemplateExceptionHandler exceptionHandler) {
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
package annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.METHOD,ElementType.FIELD})
|
||||
@Documented
|
||||
public @interface InTest {
|
||||
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package config;
|
||||
|
||||
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.mapper.MapperScannerConfigurer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
@@ -47,9 +45,6 @@ import java.util.Properties;
|
||||
@ComponentScan
|
||||
public class ContextComponentLoader {
|
||||
|
||||
@Autowired
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
/**
|
||||
* 配置数据源
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package config;
|
||||
|
||||
import adapter.FreeMarkerConfigurationAdapter;
|
||||
import extention.AlarmTplConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -18,6 +17,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import scheduler.JobScheduler;
|
||||
import scheduler.adapter.BaseJob;
|
||||
import scheduler.adapter.JobAdapter;
|
||||
import service.TplService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -27,6 +27,7 @@ import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Created by com on 2017/7/25.
|
||||
* @author 志军
|
||||
* 配置自动加载注解类
|
||||
*
|
||||
* 没有代码配置出现的情况
|
||||
@@ -168,19 +169,17 @@ public class MvcComponentLoader extends WebMvcConfigurerAdapter {
|
||||
* 1.为什么不使用配置的引用,而是新建一份配置,增加内存风险?答:配置信息如果被修改等,可能造成多线程并发问题。新建一份配置信息进行
|
||||
* temple的生成可能造成内存风险,但是这里运用了cache的方式,减轻了这个风险
|
||||
* Date: 2018/5/21/021 9:52
|
||||
* @return 返回类型描述
|
||||
* @throws Exception 异常说明
|
||||
*/
|
||||
@Bean
|
||||
public AlarmTplConfiguration AlarmTplConfiguration() throws IOException, InvocationTargetException,
|
||||
public TplService AlarmTplConfiguration() throws IOException, InvocationTargetException,
|
||||
NoSuchMethodException, InstantiationException, IllegalAccessException {
|
||||
FreeMarkerConfigurationAdapter freeMarkerConfigurationAdapter = new FreeMarkerConfigurationAdapter();
|
||||
/**
|
||||
/*
|
||||
* 这里的思路是:<br>
|
||||
* <b>1.类的有一些参数是可以使用默认设置的,我们这边给他一个使用默认设置的机会</b>
|
||||
* <b>2.类的有一些参数也可以是用户来配置的,所以说这里我们提供了一个设置参数的机会</b>
|
||||
*/
|
||||
return freeMarkerConfigurationAdapter.createConfiguration(AlarmTplConfiguration.class);
|
||||
return freeMarkerConfigurationAdapter.createConfiguration(TplService.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,18 +19,17 @@ import filter.FilterDelegator;
|
||||
import filter.WelcomeHandlingFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* Created by com on 2017/7/25.
|
||||
* <p>
|
||||
* 相当于web.xml的加载配置
|
||||
*/
|
||||
|
||||
/***
|
||||
* </p>
|
||||
* FilterRegistration.Dynamic welcomePagFilter = container.addFilter("WelcomePagFilter", new WelcomePagFilter());
|
||||
* welcomePagFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
|
||||
* 上述是配置过滤器作用的请求.
|
||||
* 这里已经包装起来了
|
||||
* @author 志军
|
||||
*/
|
||||
|
||||
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
|
||||
|
||||
|
||||
|
||||
@@ -8,19 +8,18 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
public class AnnoExceptionHandler {
|
||||
|
||||
/**
|
||||
* @a
|
||||
* @param exception
|
||||
* @return
|
||||
* 可以直接写@ExceptionHandler,不指明异常类,会自动映射
|
||||
*/
|
||||
@ExceptionHandler(CustomGenericException.class)//可以直接写@ExceptionHandler,不指明异常类,会自动映射
|
||||
public ModelAndView customGenericExceptionHnadler(CustomGenericException exception){ //还可以声明接收其他任意参数
|
||||
@ExceptionHandler(CustomGenericException.class)
|
||||
public ModelAndView customGenericExceptionHnadler(CustomGenericException exception){
|
||||
//还可以声明接收其他任意参数
|
||||
ModelAndView modelAndView = new ModelAndView("generic_error");
|
||||
modelAndView.addObject("errCode",exception.getErrCode());
|
||||
modelAndView.addObject("errMsg",exception.getErrMsg());
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)//可以直接写@EceptionHandler,IOExeption继承于Exception
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ModelAndView allExceptionHandler(Exception exception){
|
||||
ModelAndView modelAndView = new ModelAndView("generic_error");
|
||||
modelAndView.addObject("errMsg", "this is Exception.class");
|
||||
@@ -34,12 +33,12 @@ public class AnnoExceptionHandler {
|
||||
private String errCode;
|
||||
private String errMsg;
|
||||
|
||||
public String getErrCode() {
|
||||
String getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
||||
public String getErrMsg() {
|
||||
String getErrMsg() {
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ResponseObject<T> {
|
||||
*/
|
||||
private T dataView;
|
||||
|
||||
public ResponseObject(String code, String message, T value) {
|
||||
ResponseObject(String code, String message, T value) {
|
||||
this.status = code;
|
||||
this.message = message;
|
||||
this.dataView = value;
|
||||
|
||||
+5
-5
@@ -4,22 +4,22 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import service.MainService;
|
||||
import service.CommonService;
|
||||
|
||||
@Controller
|
||||
public class MainController {
|
||||
public class AopController {
|
||||
|
||||
@Autowired
|
||||
private MainService mainService;
|
||||
private CommonService commonService;
|
||||
|
||||
@RequestMapping(value = "/test/aop/param", method = RequestMethod.GET)
|
||||
public void testAopParam(){
|
||||
mainService.testAopParam(1);
|
||||
commonService.testAopParam(1);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/test/aop", method = RequestMethod.GET)
|
||||
public void testAop(){
|
||||
mainService.testAop();
|
||||
commonService.testAop();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/test/aop/getClassMessage", method = RequestMethod.GET)
|
||||
@@ -0,0 +1,29 @@
|
||||
package controller;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import service.CommonService;
|
||||
|
||||
/**
|
||||
* @author selfimpr
|
||||
* @description 测试cache缓存是否设置成功,可以在配置文件中指定位置看到cache,这边的配置是放在
|
||||
* @see config.CacheSetFromProperty
|
||||
* @date : 2017/11/11 21:46
|
||||
*/
|
||||
@Controller
|
||||
public class CacheController {
|
||||
|
||||
@Autowired
|
||||
private CommonService commonService;
|
||||
|
||||
@RequestMapping(value = "/cache/cache_test", method = RequestMethod.GET)
|
||||
public String cacheTest() {
|
||||
String cache = commonService.cacheTest();
|
||||
System.out.println(cache);
|
||||
return "success";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* @(#) EncodedTestController
|
||||
* 版权声明 网宿科技, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:网宿科技
|
||||
* <br> @author Administrator
|
||||
* <br> @description 功能描述
|
||||
* <br> 2018-12-26 22:11:24
|
||||
*/
|
||||
|
||||
package controller;
|
||||
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/encoded/test/")
|
||||
public class EncodedController {
|
||||
|
||||
/**
|
||||
* POST的方式,如果后端不设置过滤器去拦截请求并设置请求编码的话
|
||||
* 会根据Content-type的character来标识
|
||||
*/
|
||||
|
||||
@RequestMapping(value = "/post-default")
|
||||
public void postDefault(HttpServletRequest request){
|
||||
System.out.println(request.getCharacterEncoding());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/post-utf8")
|
||||
public void postUtf8(HttpServletRequest request){
|
||||
System.out.println(request.getCharacterEncoding());
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/post-gbk")
|
||||
public void postGbk(HttpServletRequest request){
|
||||
System.out.println(request.getCharacterEncoding());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/get")
|
||||
public void getGbk(HttpServletRequest request){
|
||||
System.out.println(request.getParameter("testName"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* @(#) freemarkerController
|
||||
* 版权声明 黄志军, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:黄志军
|
||||
* <br> @author selfImpr
|
||||
* <br> 2018-05-21 10:04:51
|
||||
* <br> @description
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package controller;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
import model.tpl.TplMessage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.freemarker.FreeMarkerConfigurationFactory;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||
import service.TplService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
@Controller
|
||||
public class FreemarkerController {
|
||||
|
||||
@Autowired
|
||||
private TplService tplService;
|
||||
|
||||
@RequestMapping("/freemaker")
|
||||
private String freeMaker() throws IOException, TemplateException {
|
||||
TplMessage tplMessage = new TplMessage();
|
||||
tplMessage.setIdentification("[mx1234567890]");
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy年mm月dd HH:MM:ss");
|
||||
tplMessage.setTime(dateFormat.format(new Date()));
|
||||
tplMessage.setPlatform("XXXX平台");
|
||||
tplMessage.setStatistic("123333");
|
||||
|
||||
Template temp = tplService.getTemplate("alarm.tpl");
|
||||
Writer out = new StringWriter();
|
||||
temp.process(tplMessage, out);
|
||||
System.out.print(temp.toString());
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping("springMaker")
|
||||
public void springMarker() throws IOException, TemplateException {
|
||||
FreeMarkerConfigurationFactory freeMarkerConfigurationFactory = new FreeMarkerConfigurationFactory();
|
||||
freeMarkerConfigurationFactory.setDefaultEncoding("UTF-8");
|
||||
Configuration configuration = freeMarkerConfigurationFactory.createConfiguration();
|
||||
|
||||
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
|
||||
freeMarkerConfigurer.setConfiguration(configuration);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* @(#) FullFillTimeValueController
|
||||
* 版权声明 网宿科技, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:网宿科技
|
||||
* <br> @author Administrator
|
||||
* <br> @description 功能描述
|
||||
* <br> 2018-11-24 01:14:40
|
||||
*/
|
||||
|
||||
package controller;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import model.fullFillTime.OriginTimeValue;
|
||||
import model.fullFillTime.TargetTimeValue;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import util.time.FillFullTimeValueUtil;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* @author 志军
|
||||
* 测试补时间点
|
||||
*/
|
||||
@Controller
|
||||
public class FullFillTimeValueController {
|
||||
|
||||
|
||||
@RequestMapping(value = "/time-test")
|
||||
public void fullFillTimeValue() {
|
||||
List<OriginTimeValue> originTimeValueList = Lists.newArrayList();
|
||||
originTimeValueList.add(new OriginTimeValue(1542995383, 109991));
|
||||
|
||||
List<TargetTimeValue> targetTimeValues1 = FillFullTimeValueUtil.MINUTE.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now()
|
||||
.plusDays(1), 1, originTimeValueList,
|
||||
TimeZone.getDefault());
|
||||
|
||||
|
||||
List<TargetTimeValue> targetTimeValues2 = FillFullTimeValueUtil.HOUR.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now()
|
||||
.plusDays(1), 2, originTimeValueList,
|
||||
TimeZone.getDefault());
|
||||
|
||||
List<TargetTimeValue> targetTimeValues3 = FillFullTimeValueUtil.DAY.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now()
|
||||
.plusDays(100), 10, originTimeValueList,
|
||||
TimeZone.getDefault());
|
||||
|
||||
List<TargetTimeValue> targetTimeValues4 = FillFullTimeValueUtil.MINUTE.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now()
|
||||
.plusDays(1), 1, null,
|
||||
TimeZone.getDefault());
|
||||
|
||||
|
||||
targetTimeValues1.forEach(targetTimeValue -> {
|
||||
System.out.println(targetTimeValue.getTime() + " , " + targetTimeValue.getValue());
|
||||
});
|
||||
|
||||
System.out.println("---------------------------------------------------------------------");
|
||||
|
||||
targetTimeValues2.forEach(targetTimeValue -> {
|
||||
System.out.println(targetTimeValue.getTime() + " , " + targetTimeValue.getValue());
|
||||
});
|
||||
|
||||
System.out.println("---------------------------------------------------------------------");
|
||||
|
||||
targetTimeValues3.forEach(targetTimeValue -> {
|
||||
System.out.println(targetTimeValue.getTime() + " , " + targetTimeValue.getValue());
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import util.itext.PDFUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@Controller
|
||||
public class ITextController {
|
||||
|
||||
//itext 生成pdf的 工具类
|
||||
private PDFUtils pdfUtils = new PDFUtils();
|
||||
|
||||
/** 将一个html转移成String
|
||||
String htmlString = StringEscapeUtils.unescapeHtml(html);
|
||||
* 参数介绍:
|
||||
* html:从页面获取的html信息(获取到的html是没有<html></html>标签的,需要后期加上)
|
||||
* cssName:从页面获取的css的名字
|
||||
* cssPath:css对应的绝对地址
|
||||
* htmlReadyToPdf:将html的标签加上,补充完整的html文件
|
||||
* waterMarkImage:水印的图片的名字
|
||||
* waterMarkImagePath:水印图片地址
|
||||
* templePdfname:pdf模板的名字
|
||||
* templePdfPath:pdf模板的地址
|
||||
*
|
||||
* pdfFileDirs:存放pdf文件的路径
|
||||
* pdfFileSavePath:生成pdf文件存储路径的文件
|
||||
*
|
||||
* pdfFileName:没有水印之前的pdf名字
|
||||
* pdfFilePath:没有水印的pdf的路径
|
||||
* pdfFile:没有水印的pdf文件
|
||||
* pdfFileWithWaterMarkName:加了水印的pdf文件名
|
||||
* pdfFileWithWaterMarkPath:加了水印的pdf的地址
|
||||
* pdfFileWithWaterMark:加了水印的pdf的文件
|
||||
*
|
||||
* programPath:工程地址
|
||||
*
|
||||
* responseUrl:返回到页面的工程地址
|
||||
**/
|
||||
@RequestMapping(value = "/ITextTest", method = RequestMethod.POST)
|
||||
public void itextTest(HttpServletResponse response, HttpServletRequest request, @RequestBody String body) throws Exception {
|
||||
|
||||
String html = request.getParameter("html");
|
||||
String cssName = request.getParameter("cssName");
|
||||
String htmlReadyToPdf = pdfUtils.transToHtml(html);
|
||||
String waterMarkImage = "joint_theme_pdf_stamp.png";
|
||||
String templePdfname = "joint_theme_pdf_template.pdf";
|
||||
String pdfFileName = new SimpleDateFormat("YYYYMMddHHmmss").format(new Date()) + "temporary";
|
||||
String pdfFileWithWaterMarkName = new SimpleDateFormat("YYYYMMddHHmmss").format(new Date());
|
||||
|
||||
//工程地址
|
||||
String programPath = request.getSession().getServletContext().getRealPath("");
|
||||
|
||||
//生成css的绝对地址
|
||||
String cssPath = (programPath + "css\\" + cssName).replace("\\", System.getProperty("file.separator"));
|
||||
|
||||
//生成水印的地址
|
||||
String waterMarkImagePath = (programPath + "WEB-INF\\pdf\\" + waterMarkImage).replace("\\", System.getProperty("file.separator"));
|
||||
|
||||
//生成模板地址
|
||||
String templePdfPath = (programPath + "WEB-INF\\pdf\\" + templePdfname).replace("\\", System.getProperty("file.separator"));
|
||||
|
||||
//生成存放PDF的地址
|
||||
String pdfFileDirs = programPath + "pdf" + System.getProperty("file.separator") + new SimpleDateFormat("YYYYMMdd").format(new Date());
|
||||
File pdfFileSavePath = new File(pdfFileDirs);
|
||||
if (!pdfFileSavePath.exists()) {
|
||||
pdfFileSavePath.mkdirs();
|
||||
}
|
||||
|
||||
//生成临时pdf(没有水印)和有水印的pdf的路径
|
||||
String pdfFilePath = pdfFileDirs + System.getProperty("file.separator") + pdfFileName + ".pdf";
|
||||
String pdfFileWithWaterMarkPath = pdfFileDirs + System.getProperty("file.separator") + pdfFileWithWaterMarkName + ".pdf";
|
||||
|
||||
//获取在js中显示的pdf地址
|
||||
String responseUrl = ("pdf" + "\\" + new SimpleDateFormat("YYYYMMdd").format(new Date()) + "\\" + pdfFileWithWaterMarkName + ".pdf").replace("\\", "/");
|
||||
|
||||
//生成临时pdf和最终pdf的文件
|
||||
File pdfFile = new File(pdfFilePath);
|
||||
File pdfFileWithWaterMark = new File(pdfFileWithWaterMarkPath);
|
||||
|
||||
//调用PDFUtils生成pdf文件
|
||||
PDFUtils.generalPDF(templePdfPath, pdfFilePath, cssPath, htmlReadyToPdf);
|
||||
|
||||
|
||||
//进行水印操作
|
||||
PDFUtils.sealDocument(pdfFilePath, pdfFileWithWaterMarkPath, waterMarkImagePath, "小胖子是谁:陈毅聪啊", "出具时间", "");
|
||||
//把临时pdf删掉
|
||||
pdfFile.delete();
|
||||
|
||||
PrintWriter writer = response.getWriter();
|
||||
//输出产生的PDF地址
|
||||
writer.write(responseUrl);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@Controller
|
||||
public class LoginController {
|
||||
@RequestMapping("/login/index")
|
||||
public String loginIndex() {
|
||||
return "login";
|
||||
}
|
||||
|
||||
@RequestMapping("login/loginValidate")
|
||||
public String login(HttpServletResponse response, HttpServletRequest request) {
|
||||
/**
|
||||
* 这里有一个更佳的设置用户未操作的过期时间
|
||||
* 1.即在session创建的时候把session的创建时间放在全局里面
|
||||
* 2.过滤器过滤浏览器请求时,判断session的创建时间是不是在指定的范围内
|
||||
* 如果是的话,就更新这个时间
|
||||
* 如果不是的话就清空跳转到登陆页面
|
||||
*/
|
||||
request.getSession().setAttribute("sessionTime", request.getSession().getCreationTime());
|
||||
HttpSession session = request.getSession();
|
||||
ServletContext servletContext = session.getServletContext();
|
||||
String name = request.getParameter("name");
|
||||
String password = request.getParameter("password");
|
||||
/**
|
||||
* 如何实现一个用户登陆,然后把上一个用户踢掉
|
||||
* 1.java后端可以通过servletContext来保存用户的登陆的会话信息
|
||||
* 2.当第二个用户进行登陆的时候把第一个用户的session清空
|
||||
* 3.在前台设置一个轮询的操作,判断session是否为空。
|
||||
*
|
||||
* 这个测试要联合login.html,loginTest.html来调试,还有登陆过滤器。
|
||||
* 还是不知道怎么把已经登陆的用户挤掉???不可能在每一个页面都设置一个函数来轮询监听后台的事件
|
||||
* 除非用户刷新页面,或者发送请求。
|
||||
*/
|
||||
String newSessionId = session.getId();
|
||||
//不管用户账号密码对不对都让他登陆
|
||||
session.setAttribute("name", name);
|
||||
if (servletContext.getAttribute(name) != null) {
|
||||
String oldSessionId = String.valueOf(servletContext.getAttribute(name));
|
||||
HttpSession oldSession = (HttpSession) servletContext.getAttribute(oldSessionId);
|
||||
if (!oldSessionId.equals(newSessionId)) {
|
||||
oldSession.invalidate();//清空之前的session信息
|
||||
servletContext.setAttribute(name, newSessionId);
|
||||
servletContext.setAttribute(newSessionId, session);
|
||||
}
|
||||
} else {
|
||||
servletContext.setAttribute(name, newSessionId);
|
||||
servletContext.setAttribute(newSessionId, session);
|
||||
}
|
||||
|
||||
return "loginTest";
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping("/login/test.do")
|
||||
public String loginTest() {
|
||||
return "loginTest";
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* @author selfimpr
|
||||
* @description 测试SpringConfig利用注解来实现properties配置文件的读取
|
||||
* @author 志军
|
||||
* @description 测试SpringCofig利用注解来实现properties配置文件的读取
|
||||
* @date 2017/11/11 21:26
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* @(#) RedisController
|
||||
* 版权声明 黄志军, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:黄志军
|
||||
* <br> @author selfImpr
|
||||
* <br> 2018-06-22 09:16:02
|
||||
* <br> @description
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package controller;
|
||||
|
||||
import model.redis.RedisUser;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 为了方便使用,直接把到层的操作放在这里面
|
||||
*/
|
||||
@Controller
|
||||
public class RedisController {
|
||||
|
||||
@Resource(name = "redisTemplate")
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* 非复杂对象的操作
|
||||
* 参考地址: http://www.cnblogs.com/qlqwjy/p/8562703.html
|
||||
*/
|
||||
|
||||
@RequestMapping(value = "/redis/simple", method = RequestMethod.GET)
|
||||
public String simpleOperation() {
|
||||
//String操作
|
||||
redisTemplate.opsForValue().set("myStr", "skyLine");
|
||||
redisTemplate.delete("myStr");
|
||||
redisTemplate.opsForValue().set("myStr", "skyLine");
|
||||
System.out.println(redisTemplate.opsForValue().get("myStr"));
|
||||
System.out.println("---------------");
|
||||
// List读写
|
||||
redisTemplate.delete("myList");
|
||||
redisTemplate.opsForList().rightPush("myList", "T");
|
||||
redisTemplate.opsForList().rightPush("myList", "L");
|
||||
redisTemplate.opsForList().leftPush("myList", "A");
|
||||
List<String> listCache = redisTemplate.opsForList().range("myList", 0, -1);
|
||||
for (String s : listCache) {
|
||||
System.out.println(s);
|
||||
}
|
||||
System.out.println("---------------");
|
||||
// Set读写
|
||||
redisTemplate.delete("mySet");
|
||||
redisTemplate.opsForSet().add("mySet", "A");
|
||||
redisTemplate.opsForSet().add("mySet", "B");
|
||||
redisTemplate.opsForSet().add("mySet", "C");
|
||||
Set<String> setCache = redisTemplate.opsForSet().members("mySet");
|
||||
for (String s : setCache) {
|
||||
System.out.println(s);
|
||||
}
|
||||
System.out.println("---------------");
|
||||
|
||||
// Hash读写
|
||||
redisTemplate.delete("myHash");
|
||||
redisTemplate.opsForHash().put("myHash", "BJ", "北京");
|
||||
redisTemplate.opsForHash().put("myHash", "SH", "上海");
|
||||
redisTemplate.opsForHash().put("myHash", "HN", "河南");
|
||||
Map<String, String> hashCache = redisTemplate.opsForHash().entries("myHash");
|
||||
for (Map.Entry<String, String> entry : hashCache.entrySet()) {
|
||||
System.out.println(entry.getKey() + " - " + entry.getValue());
|
||||
}
|
||||
System.out.println("---------------");
|
||||
return "";
|
||||
}
|
||||
|
||||
//操作复杂的数据类型:自定义的数据类型
|
||||
@RequestMapping(value = "/redis/complex", method = RequestMethod.GET)
|
||||
public void conplexOperation() {
|
||||
//新增两个用户
|
||||
RedisUser user = new RedisUser();
|
||||
user.setId("aaaaaa");
|
||||
user.setSex("男");
|
||||
user.setUserName("小胖子");
|
||||
user.setAge(25);
|
||||
RedisUser user1 = new RedisUser();
|
||||
user1.setId("bbbbbb");
|
||||
user1.setSex("男");
|
||||
user1.setUserName("大胖子");
|
||||
user1.setAge(50);
|
||||
|
||||
add(user);
|
||||
add(user1);
|
||||
delete(user.getId());
|
||||
user1.setAge(100);
|
||||
update(user1);
|
||||
|
||||
RedisUser user2 = get(user1.getId());
|
||||
System.out.print("获取到的对象信息" + user2.toString());
|
||||
}
|
||||
|
||||
|
||||
public boolean add(final RedisUser user) {
|
||||
return (boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
|
||||
ValueOperations<String, Serializable> valueOper = redisTemplate.opsForValue();
|
||||
valueOper.set(user.getId(), user);
|
||||
return true;
|
||||
}, false, true);
|
||||
}
|
||||
|
||||
public boolean batchAdd(final List<RedisUser> users) {
|
||||
return (boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
|
||||
ValueOperations<String, Serializable> valueOper = redisTemplate.opsForValue();
|
||||
for (RedisUser user : users) {
|
||||
valueOper.set(user.getId(), user);
|
||||
}
|
||||
return true;
|
||||
}, false, true);
|
||||
}
|
||||
|
||||
public void delete(String key) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(key);
|
||||
delete(list);
|
||||
}
|
||||
|
||||
public void delete(List<String> keys) {
|
||||
redisTemplate.delete(keys);
|
||||
}
|
||||
|
||||
public boolean update(final RedisUser user) {
|
||||
String id = user.getId();
|
||||
if (get(id) == null) {
|
||||
throw new NullPointerException("数据行不存在, key = " + id);
|
||||
}
|
||||
return (boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
|
||||
ValueOperations<String, Serializable> valueOper = redisTemplate.opsForValue();
|
||||
valueOper.set(user.getId(), user);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public RedisUser get(final String keyId) {
|
||||
return (RedisUser) redisTemplate.execute((RedisCallback<RedisUser>) connection -> {
|
||||
ValueOperations<String, Serializable> operations = redisTemplate.opsForValue();
|
||||
RedisUser user = (RedisUser) operations.get(keyId);
|
||||
return user;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* @(#) RequestLimitController
|
||||
* 版权声明 网宿科技, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:网宿科技
|
||||
* <br> @author huangzj1
|
||||
* <br> @description 功能描述
|
||||
* <br> 2018-12-16 17:27:24
|
||||
*/
|
||||
|
||||
package controller;
|
||||
|
||||
import logic.requestLimit.RequestLimit;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* ${DESCRIPTION}
|
||||
*
|
||||
* @author huangzj1
|
||||
* @date 2018-12-16 17:27
|
||||
*/
|
||||
@Controller
|
||||
public class RequestLimitController {
|
||||
|
||||
@RequestMapping(value = "/request/limit")
|
||||
@RequestLimit(time = 55, count = 2, waits = 100)
|
||||
@ResponseBody
|
||||
public String requestLimit(HttpServletRequest request) {
|
||||
System.out.println("我被打扰了");
|
||||
return "我被打扰了";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package controller;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import tool.WangEditorTool;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
|
||||
/**
|
||||
* @author 志军
|
||||
* 用来测试WangEditor插件
|
||||
*/
|
||||
|
||||
@Controller
|
||||
@RequestMapping("")
|
||||
public class WangEditorController {
|
||||
|
||||
@RequestMapping(value = "/Editor/index",method = RequestMethod.GET)
|
||||
public String index(){
|
||||
return "wangEditor";
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping("/Editor/updateImage")
|
||||
public void updateImage(HttpServletRequest request, HttpServletResponse response) throws FileUploadException, InterruptedException, IOException {
|
||||
WangEditorTool tool = new WangEditorTool(request);
|
||||
tool.execRequest();
|
||||
String fileName = "http://localhost:8033/Spring/" + tool.getMap().get("FilePath").toString().substring(78);
|
||||
|
||||
String href = "<img src='"+ fileName + "' style=\"max-width: 100%;\"></p><p><br></p>";
|
||||
System.out.print(href);
|
||||
|
||||
//直接返回会报错,因为富文本不接受这样格式的报文返回
|
||||
// sendResponse(response,href);
|
||||
sendResponseJson(response,href);
|
||||
System.out.println("富文本图片进来了");
|
||||
}
|
||||
|
||||
@RequestMapping("/Editor/sendText")
|
||||
public void sendText(HttpServletRequest request, HttpServletResponse response, @RequestBody String body) throws UnsupportedEncodingException {
|
||||
|
||||
//通过过在MvcComponentLoder配置了一个编码过滤器,所以这里解析是正常的。我们可以把这个东西保存到数据库
|
||||
System.out.println(request.getParameter("data"));
|
||||
|
||||
System.out.println("富文本上传数据进来了");
|
||||
}
|
||||
|
||||
@RequestMapping("/Editor/getDataAndShow")
|
||||
public void getDataAndShow(HttpServletResponse response,HttpServletRequest request){
|
||||
String data = "<p>欢迎使用 <b>wangEditor</b> 富文本编辑器<img src=\"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=714624164,1707887834&fm=27&gp=0.jpg\" style=\"max-width: 100%;\"></p><p><br></p>";
|
||||
|
||||
sendResponse(response,data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送数据到前端 -- 通过设置response的编码保证正确的返回
|
||||
*/
|
||||
public void sendResponse(HttpServletResponse response,String data) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
PrintWriter writer = null;
|
||||
try {
|
||||
writer = response.getWriter();
|
||||
writer.print(data);
|
||||
}catch(Exception ex){
|
||||
//logger输出堆栈信息
|
||||
}finally{
|
||||
assert writer != null;
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送数据到前端 -- 通过设置response的编码保证正确的返回
|
||||
*/
|
||||
public void sendResponseJson(HttpServletResponse response,String data) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json");
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("errno","0");
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.add(data);
|
||||
jsonObject.put("data",jsonArray);
|
||||
PrintWriter writer = null;
|
||||
try {
|
||||
writer = response.getWriter();
|
||||
|
||||
writer.print(jsonObject);
|
||||
} catch(Exception ex){
|
||||
ex.printStackTrace();
|
||||
}finally{
|
||||
assert writer != null;
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
|
||||
package extention;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Version;
|
||||
|
||||
public class AlarmTplConfiguration extends Configuration {
|
||||
public AlarmTplConfiguration() {
|
||||
}
|
||||
|
||||
public AlarmTplConfiguration(Version incompatibleImprovements) {
|
||||
super(incompatibleImprovements);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import javax.servlet.Filter;
|
||||
|
||||
/**
|
||||
* 过滤器委托.(过滤器类)
|
||||
* @author 志军
|
||||
* Created by com on 2017/8/21.
|
||||
*/
|
||||
public class FilterDelegator {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package filter;
|
||||
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import util.MessageUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.annotation.WebInitParam;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 这里有一个更佳的设置用户未操作的过期时间
|
||||
* 1.即在session创建的时候把session的创建时间放在全局里面 (应该是登陆时间)
|
||||
* 2.过滤器过滤浏览器请求时,判断session的创建时间是不是在指定的范围内
|
||||
* 如果是的话,就更新这个时间
|
||||
* 如果不是的话就清空跳转到登陆页面
|
||||
*
|
||||
* 当这个未过期的登陆时间判断通过以后,去过滤器链发送请求会再经过这个过滤器,更新一次时间,不过这是没关系的啊。
|
||||
* 只做do请求的拦截
|
||||
*
|
||||
* 所有的测试请求都在 LoginController 中,与本工程其他无关
|
||||
*/
|
||||
@WebFilter(urlPatterns = "*.do", initParams = {@WebInitParam(name = "EXCLUDED_PAGES", value = "/login;/login/index")})
|
||||
public class LoginFilter implements Filter {
|
||||
|
||||
private Logger logger = Logger.getLogger(LoginFilter.class);
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) {
|
||||
System.out.println("登陆验证过滤器");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletRequest request1 = (HttpServletRequest) request;
|
||||
HttpServletResponse response1 = (HttpServletResponse) response;
|
||||
HttpSession session = request1.getSession();
|
||||
String url = request1.getRequestURI();
|
||||
String name = (String) session.getAttribute("name");
|
||||
String password = request1.getParameter("password");
|
||||
String userCode = request1.getRemoteUser();
|
||||
String userRole = (String) session.getAttribute("role");
|
||||
System.out.println(password + " " + userCode + " " + userRole );
|
||||
//登录界面展示不拦截,直接放过(其他界面需要验证登录者的信息)
|
||||
if (url.contains("/login/index") || url.contains("/login/loginValidate")) {
|
||||
chain.doFilter(request, response);
|
||||
logger.debug("登陆请求不验证拦劫 ");
|
||||
return;
|
||||
}
|
||||
|
||||
String processUrl = buildWelcomeRequestUrl(request1);
|
||||
|
||||
//如果用户名是空,说明没有登录信息,需要重定向到登录界面重新登录
|
||||
if (StringUtils.isBlank(name)) {
|
||||
response1.sendRedirect(processUrl + "/login/index");
|
||||
return;
|
||||
}
|
||||
long createTime = Long.parseLong(String.valueOf(session.getAttribute("sessionTime")));
|
||||
long nowTime = Long.parseLong(String.valueOf(System.currentTimeMillis()));
|
||||
|
||||
/*
|
||||
判断session是否过期,这边是需要把过期的用户强制退出
|
||||
设置不操作的超时时间 --比如10秒 -- 这里设置时间久一点,是为了测试后一个用户登陆把上一个用户挤掉的例子
|
||||
*/
|
||||
long overTime = 5000000;
|
||||
if (nowTime - createTime > overTime) {
|
||||
logger.debug("session过期" + (nowTime - createTime));
|
||||
session.invalidate();//清除session信息?
|
||||
response1.sendRedirect(processUrl + "/login/index");
|
||||
} else {
|
||||
session.setAttribute("sessionTime", nowTime);
|
||||
logger.debug("session没有过期");
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String buildWelcomeRequestUrl(HttpServletRequest request) {
|
||||
String pattern = "{0}://{1}:{2}{3}";
|
||||
String scheme = request.getScheme();
|
||||
String serverName = request.getServerName();
|
||||
String serverPort = String.valueOf(request.getServerPort());
|
||||
String contextPath = org.springframework.util.StringUtils.isEmpty(request.getContextPath()) ? "" : request.getContextPath();
|
||||
return MessageUtils.format(pattern, scheme, serverName, serverPort, contextPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 处理Welcome请求路径的过滤器:在Welcome请求路径的末尾添加/,解决Servlet 3.0+不能以编程方式来配置Welcome页面的问题。
|
||||
*
|
||||
* @author Kison 2017年7月6日
|
||||
*/
|
||||
public class WelcomeHandlingFilter implements Filter {
|
||||
|
||||
|
||||
@@ -52,8 +52,6 @@ public class RequestLimitAspect {
|
||||
if (body.getDelayClickUtilTIme() != null && DateTimeUtil.getNowSeconds() - body.getDelayClickUtilTIme() <= limit.waits()) {
|
||||
System.out.println("超过点击次数,还需要等待" + (limit.waits() - (DateTimeUtil.getNowSeconds() - body.getDelayClickUtilTIme())) + "秒");
|
||||
throw new RequestLimitException("超过点击次数,还需要等待" + (limit.waits() - (DateTimeUtil.getNowSeconds() - body.getDelayClickUtilTIme())) + "秒");
|
||||
}else{
|
||||
|
||||
}
|
||||
|
||||
//如果最后一次点击在规定时间之内并且点击次数超过规定点击次数.进入延迟点击
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
package model.fullFillTime;
|
||||
|
||||
/**
|
||||
* 原始的时间点
|
||||
* @author huangzj
|
||||
*/
|
||||
public class OriginTimeValue {
|
||||
|
||||
/**
|
||||
* 时间
|
||||
*/
|
||||
private long time;
|
||||
|
||||
/**
|
||||
* 数值
|
||||
*/
|
||||
private long value;
|
||||
|
||||
public OriginTimeValue(long time, long value) {
|
||||
this.time = time;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
package model.fullFillTime;
|
||||
|
||||
/**
|
||||
* 补时间点后的对象
|
||||
*/
|
||||
public class TargetTimeValue {
|
||||
private long time;
|
||||
/**
|
||||
* 统计值,其中null值表示没有数据
|
||||
*/
|
||||
private Long value;
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public void setValue(Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public Long getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* @(#) RedisUser
|
||||
* 版权声明 网宿科技, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:网宿科技
|
||||
* <br> @author Administrator
|
||||
* <br> @description 功能描述
|
||||
* <br> 2018-11-13 20:42:05
|
||||
*/
|
||||
|
||||
package model.redis;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class RedisUser implements Serializable {
|
||||
|
||||
/**
|
||||
* 这个是用来测试redis存储复杂对象方法的对象
|
||||
*/
|
||||
private static final long serialVersionUID = -5244288298702801619L;
|
||||
|
||||
private String id;
|
||||
|
||||
private String userName;
|
||||
|
||||
private String sex;
|
||||
|
||||
private int age;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(String sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User [id=" + id + ", userName=" + userName + ", sex=" + sex + ", age=" + age + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* @(#) TplMessage
|
||||
* 版权声明 网宿科技, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:网宿科技
|
||||
* <br> @author Administrator
|
||||
* <br> @description 功能描述
|
||||
* <br> 2018-11-13 20:42:05
|
||||
*/
|
||||
|
||||
package model.tpl;
|
||||
|
||||
public class TplMessage {
|
||||
|
||||
|
||||
private String identification;
|
||||
|
||||
private String time;
|
||||
|
||||
private String platform;
|
||||
|
||||
private String statistic;
|
||||
|
||||
public String getIdentification() {
|
||||
return identification;
|
||||
}
|
||||
|
||||
public void setIdentification(String identification) {
|
||||
this.identification = identification;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public String getStatistic() {
|
||||
return statistic;
|
||||
}
|
||||
|
||||
public void setStatistic(String statistic) {
|
||||
this.statistic = statistic;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,14 @@ package service;
|
||||
* Created by Administrator on 2017/7/18.
|
||||
* @author 志军
|
||||
*/
|
||||
public interface MainService {
|
||||
public interface CommonService {
|
||||
|
||||
String testAopParam(int a);
|
||||
|
||||
void testAop();
|
||||
|
||||
|
||||
String cacheTest();
|
||||
|
||||
}
|
||||
|
||||
+9
-3
@@ -1,7 +1,7 @@
|
||||
package service;
|
||||
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
||||
/**
|
||||
@@ -9,8 +9,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* @author 志军
|
||||
*/
|
||||
@Service
|
||||
@Transactional
|
||||
public class MainServiceImpl implements MainService {
|
||||
public class CommonServiceImpl implements CommonService {
|
||||
|
||||
|
||||
@Override
|
||||
@@ -23,4 +22,11 @@ public class MainServiceImpl implements MainService {
|
||||
System.out.println("测试Aop");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "bm")
|
||||
public String cacheTest() {
|
||||
System.out.println("我是cache,我执行了");
|
||||
return "123444";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* @(#) AlarmTplConfiguration
|
||||
* 版权声明 网宿科技, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:网宿科技
|
||||
* <br> @author Administrator
|
||||
* <br> @description 功能描述
|
||||
* <br> 2018-11-13 20:34:52
|
||||
*/
|
||||
|
||||
package service;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Version;
|
||||
|
||||
public class TplService extends Configuration {
|
||||
public TplService() {
|
||||
}
|
||||
|
||||
public TplService(Version incompatibleImprovements) {
|
||||
super(incompatibleImprovements);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
package tool;
|
||||
|
||||
import org.apache.commons.fileupload.FileItemIterator;
|
||||
import org.apache.commons.fileupload.FileItemStream;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.fileupload.util.Streams;
|
||||
import util.Base64Util;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author 志军
|
||||
* 配合Wangeditor一起处理的工具类
|
||||
*/
|
||||
public class WangEditorTool {
|
||||
//对request请求进行保存
|
||||
private HttpServletRequest request;
|
||||
//保存文件名称
|
||||
private String fileName;
|
||||
//保存文件的后缀
|
||||
private String suffix;
|
||||
//保存完整的文件名
|
||||
private String completeFileName;
|
||||
//用来存储FileItemStream的信息,看最后这些东西是什么
|
||||
private ArrayList<String> fileItemStreamNames = new ArrayList<String>();
|
||||
//用来保存传过来的参数?
|
||||
private HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
//用来缓存文件流的 --发现说流是缓存不下来的,因为流一旦读取完毕就是close状态
|
||||
private InputStream inputStream;
|
||||
//通过list来缓存byte,因为在文件读取的时候这个byte大小可能不一定全是那么大就会大致,写入失败
|
||||
private List<byte[]> byteList = new ArrayList<byte[]>();
|
||||
|
||||
|
||||
public WangEditorTool() {
|
||||
}
|
||||
|
||||
public WangEditorTool(boolean b) {
|
||||
if (!b) {
|
||||
this.completeFileName = "我怀疑你是一个小胖子";
|
||||
}
|
||||
}
|
||||
|
||||
public WangEditorTool(HttpServletRequest request) {
|
||||
System.out.println(request.getParameter("name"));
|
||||
System.out.println(request.getRequestURI());
|
||||
this.request = request;
|
||||
|
||||
}
|
||||
|
||||
//参考地址:https://commons.apache.org/proper/commons-fileupload/streaming.html
|
||||
/**
|
||||
* 通过spring提供的类来实现request的解析,读取他的流和流中对应的数据
|
||||
* 请注意field和非field的区别
|
||||
*/
|
||||
public WangEditorTool execRequest() throws FileUploadException, IOException, InterruptedException {
|
||||
|
||||
//判断是不是ajax请求?
|
||||
boolean isAjaxUpload = request.getHeader("X_Requested_With") != null;
|
||||
//判断是不是文件请求
|
||||
if (!ServletFileUpload.isMultipartContent(request)) {
|
||||
return new WangEditorTool(false);
|
||||
}
|
||||
//spring提供的对于request请求携带文件信息的处理工具类
|
||||
ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory());
|
||||
//设置头部编码?
|
||||
if (isAjaxUpload) {
|
||||
servletFileUpload.setHeaderEncoding("UTF-8");
|
||||
}
|
||||
//解析获取request中的流
|
||||
FileItemIterator iterator = servletFileUpload.getItemIterator(request);
|
||||
//用来判断是否没有数据和接收数据
|
||||
FileItemStream fileItemStream = null;
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
//对迭代器进行读取,这里的读取是跟浏览器进行信息交互,所以流打开和读取是一次性的,为了多次读取,试试能不能把流缓存在本地
|
||||
fileItemStream = iterator.next();
|
||||
fileItemStreamNames.add("name = " + fileItemStream.getName());
|
||||
fileItemStreamNames.add("fieldNames = " + fileItemStream.getFieldName());
|
||||
//判断是不是表单数据
|
||||
if (fileItemStream.isFormField()) {
|
||||
//打开流
|
||||
InputStream inputStream = fileItemStream.openStream();
|
||||
String id = fileItemStream.getFieldName();
|
||||
String value = Streams.asString(inputStream, "UTF-8");
|
||||
//进行表单数据的缓存 -- 该流已经结束读取 和浏览器之间的读取
|
||||
map.put(id, value);
|
||||
//关闭流
|
||||
inputStream.close();
|
||||
}
|
||||
//不是表单数据,是文件?进行读取? --文件不是表单数据
|
||||
if (!fileItemStream.isFormField()) {
|
||||
//文件名
|
||||
String fileName = fileItemStream.getName();
|
||||
//文件类型
|
||||
String ContentType = fileItemStream.getContentType();
|
||||
map.put("fileName", fileName);
|
||||
map.put("ContentType", ContentType);
|
||||
|
||||
InputStream inputStream = fileItemStream.openStream();
|
||||
//文件大小?
|
||||
int size = inputStream.available();
|
||||
map.put("size", size);
|
||||
map.put("inputStream", inputStream);
|
||||
this.inputStream = inputStream;
|
||||
//读取文件的字节
|
||||
byte[] bytes = new byte[size];
|
||||
//用来读取的字节大小
|
||||
byte[] bytes1 = new byte[1024];
|
||||
|
||||
int read;
|
||||
String path = getRandomFilePath(request, bytes, fileName);
|
||||
map.put("FilePath",path);
|
||||
BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream(new File(path)));
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
StringBuilder bytesS = new StringBuilder();
|
||||
//放在外面读而不是把字节存下来读取,可以保证顺序存储不出错
|
||||
while ((read = inputStream.read(bytes1)) != -1) {
|
||||
bof.write(bytes1,0,read);
|
||||
byteList.add(bytes1);
|
||||
bytesS.append(Arrays.toString(bytes1));
|
||||
byteArrayOutputStream.write(bytes1, 0, read);
|
||||
}
|
||||
map.put("byteList",byteList);
|
||||
map.put("bytes", bytesS.toString());
|
||||
byte[] fileByteArray = byteArrayOutputStream.toByteArray();
|
||||
byteArrayOutputStream.close();
|
||||
|
||||
//也就是说我不可能缓存流,但是可以把流中的字节缓存下来。
|
||||
map.put("fileByteArray",fileByteArray);
|
||||
fileByteArray = (byte[]) map.get("fileByteArray");
|
||||
|
||||
//将字节转为String?类似在数据库中的存储
|
||||
String fileBase64 = Base64Util.encode(fileByteArray);
|
||||
inputStream.close();
|
||||
System.out.println(fileBase64);
|
||||
|
||||
Thread.sleep(1000);
|
||||
//对流进行转换并读写
|
||||
writeStringToByte(fileBase64,fileName);
|
||||
|
||||
Thread.sleep(1000);
|
||||
//对流进行转换并读写 ---不进行转码
|
||||
writeStringToByte(fileName,fileByteArray);
|
||||
}
|
||||
}
|
||||
|
||||
//如果遍历没给值,说明为空
|
||||
if (fileItemStream == null) {
|
||||
return new WangEditorTool(false);
|
||||
}
|
||||
|
||||
return new WangEditorTool(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过转成base64的String 模拟进数据库,在回头去把数据decode回来成byte[],然后写成文件
|
||||
*/
|
||||
public void writeStringToByte(String fileBase64,String fileName) throws IOException {
|
||||
String path = getRandomFilePath(request, new byte[0], fileName);
|
||||
BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream(new File(path)));
|
||||
byte[] bytes = Base64Util.decodeByte(fileBase64);
|
||||
|
||||
bof.write(bytes);
|
||||
bof.flush();
|
||||
bof.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过byteArrayOutputStream来获取这个byte流的信息,然后直接传进来读取
|
||||
* 实验一下如果缓存byte在本地可以读取 的操作
|
||||
*/
|
||||
public void writeStringToByte(String fileName,byte[] unicodeByte) throws IOException {
|
||||
String path = getRandomFilePath(request, new byte[0], fileName);
|
||||
|
||||
BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream(new File(path)));
|
||||
InputStream fis = new ByteArrayInputStream(unicodeByte);
|
||||
byte[] bytes = new byte[1024];
|
||||
|
||||
int read;
|
||||
while((read = fis.read(bytes) )!=-1){
|
||||
bof.write(bytes,0,read);
|
||||
}
|
||||
|
||||
bof.flush();
|
||||
fis.close();
|
||||
bof.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 流存不下来,他会自动关闭掉,那我应该怎么办??? -- 我尝试用缓存的byte来做???
|
||||
*/
|
||||
public void getStreamAndRead(String fileName) throws IOException {
|
||||
//用来读取的字节大小
|
||||
byte[] bytes1 = new byte[1024];
|
||||
|
||||
String bytesS = (String) map.get("bytes");
|
||||
|
||||
String path = getRandomFilePath(request, bytes1, fileName);
|
||||
BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream(new File(path)));
|
||||
|
||||
byte[] bytes2 = bytesS.getBytes(StandardCharsets.UTF_8);
|
||||
System.out.println(bytesS);
|
||||
|
||||
bof.write(bytes2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进行缓存参数的输出
|
||||
*/
|
||||
public void getThingsInRequest() {
|
||||
System.out.println("list数据");
|
||||
for (int i = 0; i < fileItemStreamNames.size(); i++) {
|
||||
System.out.println((i + 1) + ":" + fileItemStreamNames.get(i) + ";");
|
||||
}
|
||||
System.out.println("map的数据");
|
||||
for (Map.Entry<String, Object> esi : map.entrySet()) {
|
||||
System.out.println(esi.getKey() + ":" + esi.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名和文件地址
|
||||
*/
|
||||
public String getRandomFilePath(HttpServletRequest request, byte[] bytes, String fileName) throws IOException {
|
||||
String springPath;
|
||||
springPath = request.getServletContext().getRealPath("/");
|
||||
SimpleDateFormat.getInstance().format(new Date());
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String dir = simpleDateFormat.format(new Date());
|
||||
System.out.println(dir);
|
||||
//通过正确的间隔符来标识文件路径 + File.separator
|
||||
springPath = springPath + dir + File.separator;
|
||||
System.out.println("文件路径" + springPath);
|
||||
File file1 = new File(springPath);
|
||||
if (file1.exists() && file1.isDirectory()) {
|
||||
} else {
|
||||
file1.mkdirs();
|
||||
}
|
||||
|
||||
springPath = springPath + File.separator + fileName;
|
||||
File file = new File(springPath);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
return springPath;
|
||||
}
|
||||
|
||||
public HttpServletRequest getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public void setRequest(HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public HashMap getMap(){
|
||||
return this.map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
package util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* 该工具是很久之前在网上找的,现在已经忘记了对应的代码地址
|
||||
*/
|
||||
public class Base64Util {
|
||||
private static final char[] S_BASE64CHAR = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
|
||||
private static final char S_BASE64PAD = '=';
|
||||
private static final byte[] S_DECODETABLE = new byte[128];
|
||||
private static final char EQUAL_SIGN = '=';
|
||||
|
||||
public Base64Util() {
|
||||
}
|
||||
|
||||
private static int decode0(char[] ibuf, byte[] obuf, int wp) {
|
||||
int outlen = 3;
|
||||
if (ibuf[3] == EQUAL_SIGN) {
|
||||
outlen = 2;
|
||||
}
|
||||
|
||||
if (ibuf[2] ==EQUAL_SIGN ) {
|
||||
outlen = 1;
|
||||
}
|
||||
|
||||
int b0 = S_DECODETABLE[ibuf[0]];
|
||||
int b1 = S_DECODETABLE[ibuf[1]];
|
||||
int b2 = S_DECODETABLE[ibuf[2]];
|
||||
int b3 = S_DECODETABLE[ibuf[3]];
|
||||
switch (outlen) {
|
||||
case 1:
|
||||
obuf[wp] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3);
|
||||
return 1;
|
||||
case 2:
|
||||
obuf[wp++] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3);
|
||||
obuf[wp] = (byte) (b1 << 4 & 240 | b2 >> 2 & 15);
|
||||
return 2;
|
||||
case 3:
|
||||
obuf[wp++] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3);
|
||||
obuf[wp++] = (byte) (b1 << 4 & 240 | b2 >> 2 & 15);
|
||||
obuf[wp] = (byte) (b2 << 6 & 192 | b3 & 63);
|
||||
return 3;
|
||||
default:
|
||||
throw new RuntimeException("Internal Errror");
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] decode(char[] data, int off, int len) {
|
||||
char[] ibuf = new char[4];
|
||||
int ibufcount = 0;
|
||||
byte[] obuf = new byte[len / 4 * 3 + 3];
|
||||
int obufcount = 0;
|
||||
|
||||
for (int i = off; i < off + len; ++i) {
|
||||
char ch = data[i];
|
||||
if (ch == '=' || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != 127) {
|
||||
ibuf[ibufcount++] = ch;
|
||||
if (ibufcount == ibuf.length) {
|
||||
ibufcount = 0;
|
||||
obufcount += decode0(ibuf, obuf, obufcount);
|
||||
}
|
||||
}
|
||||
}
|
||||
return decodeResult(obufcount,obuf);
|
||||
}
|
||||
|
||||
private static byte[] decodeResult(int obufcount, byte[] obuf) {
|
||||
if (obufcount == obuf.length) {
|
||||
return obuf;
|
||||
} else {
|
||||
byte[] ret = new byte[obufcount];
|
||||
System.arraycopy(obuf, 0, ret, 0, obufcount);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] decode(String data) {
|
||||
char[] ibuf = new char[4];
|
||||
int ibufcount = 0;
|
||||
byte[] obuf = new byte[data.length() / 4 * 3 + 3];
|
||||
int obufcount = 0;
|
||||
|
||||
for (int i = 0; i < data.length(); ++i) {
|
||||
char ch = data.charAt(i);
|
||||
if (ch == '=' || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != 127) {
|
||||
ibuf[ibufcount++] = ch;
|
||||
if (ibufcount == ibuf.length) {
|
||||
ibufcount = 0;
|
||||
obufcount += decode0(ibuf, obuf, obufcount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return decodeResult(obufcount,obuf);
|
||||
}
|
||||
|
||||
public static void decode(char[] data, int off, int len, OutputStream ostream) throws IOException {
|
||||
char[] ibuf = new char[4];
|
||||
int ibufcount = 0;
|
||||
byte[] obuf = new byte[3];
|
||||
|
||||
for (int i = off; i < off + len; ++i) {
|
||||
char ch = data[i];
|
||||
decodeProcess(ch,ibuf,ibufcount,ostream,obuf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void decodeProcess(char ch, char[] ibuf, int ibufcount, OutputStream ostream, byte[] obuf) throws IOException {
|
||||
if (ch == '=' || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != 127) {
|
||||
ibuf[ibufcount++] = ch;
|
||||
if (ibufcount == ibuf.length) {
|
||||
ibufcount = 0;
|
||||
int obufcount = decode0(ibuf, obuf, 0);
|
||||
ostream.write(obuf, 0, obufcount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void decode(String data, OutputStream ostream) throws IOException {
|
||||
char[] ibuf = new char[4];
|
||||
int ibufcount = 0;
|
||||
byte[] obuf = new byte[3];
|
||||
|
||||
for (int i = 0; i < data.length(); ++i) {
|
||||
char ch = data.charAt(i);
|
||||
decodeProcess(ch,ibuf,ibufcount,ostream,obuf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String encode(byte[] data) {
|
||||
return encode(data, 0, data.length);
|
||||
}
|
||||
|
||||
public static String encode(byte[] data, int off, int len) {
|
||||
if (len <= 0) {
|
||||
return "";
|
||||
} else {
|
||||
char[] out = new char[len / 3 * 4 + 4];
|
||||
int rindex = off;
|
||||
int windex = 0;
|
||||
|
||||
int rest;
|
||||
int i;
|
||||
for (rest = len; rest >= 3; rest -= 3) {
|
||||
i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255);
|
||||
out[windex++] = S_BASE64CHAR[i >> 18];
|
||||
out[windex++] = S_BASE64CHAR[i >> 12 & 63];
|
||||
out[windex++] = S_BASE64CHAR[i >> 6 & 63];
|
||||
out[windex++] = S_BASE64CHAR[i & 63];
|
||||
rindex += 3;
|
||||
}
|
||||
|
||||
if (rest == 1) {
|
||||
i = data[rindex] & 255;
|
||||
out[windex++] = S_BASE64CHAR[i >> 2];
|
||||
out[windex++] = S_BASE64CHAR[i << 4 & 63];
|
||||
out[windex++] = '=';
|
||||
out[windex++] = '=';
|
||||
} else if (rest == 2) {
|
||||
i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255);
|
||||
out[windex++] = S_BASE64CHAR[i >> 10];
|
||||
out[windex++] = S_BASE64CHAR[i >> 4 & 63];
|
||||
out[windex++] = S_BASE64CHAR[i << 2 & 63];
|
||||
out[windex++] = '=';
|
||||
}
|
||||
|
||||
return new String(out, 0, windex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void encode(byte[] data, int off, int len, OutputStream ostream) throws IOException {
|
||||
if (len > 0) {
|
||||
byte[] out = new byte[4];
|
||||
int rindex = off;
|
||||
|
||||
int rest;
|
||||
int i;
|
||||
for (rest = len; rest >= 3; rest -= 3) {
|
||||
i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255);
|
||||
out[0] = (byte) S_BASE64CHAR[i >> 18];
|
||||
out[1] = (byte) S_BASE64CHAR[i >> 12 & 63];
|
||||
out[2] = (byte) S_BASE64CHAR[i >> 6 & 63];
|
||||
out[3] = (byte) S_BASE64CHAR[i & 63];
|
||||
ostream.write(out, 0, 4);
|
||||
rindex += 3;
|
||||
}
|
||||
|
||||
if (rest == 1) {
|
||||
i = data[rindex] & 255;
|
||||
out[0] = (byte) S_BASE64CHAR[i >> 2];
|
||||
out[1] = (byte) S_BASE64CHAR[i << 4 & 63];
|
||||
out[2] = 61;
|
||||
out[3] = 61;
|
||||
ostream.write(out, 0, 4);
|
||||
} else if (rest == 2) {
|
||||
i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255);
|
||||
out[0] = (byte) S_BASE64CHAR[i >> 10];
|
||||
out[1] = (byte) S_BASE64CHAR[i >> 4 & 63];
|
||||
out[2] = (byte) S_BASE64CHAR[i << 2 & 63];
|
||||
out[3] = 61;
|
||||
ostream.write(out, 0, 4);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void encode(byte[] data, int off, int len, Writer writer) throws IOException {
|
||||
if (len > 0) {
|
||||
char[] out = new char[4];
|
||||
int rindex = off;
|
||||
int rest = len;
|
||||
int output = 0;
|
||||
|
||||
int i;
|
||||
while (rest >= 3) {
|
||||
i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255);
|
||||
out[0] = S_BASE64CHAR[i >> 18];
|
||||
out[1] = S_BASE64CHAR[i >> 12 & 63];
|
||||
out[2] = S_BASE64CHAR[i >> 6 & 63];
|
||||
out[3] = S_BASE64CHAR[i & 63];
|
||||
writer.write(out, 0, 4);
|
||||
rindex += 3;
|
||||
rest -= 3;
|
||||
output += 4;
|
||||
if (output % 76 == 0) {
|
||||
writer.write("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (rest == 1) {
|
||||
i = data[rindex] & 255;
|
||||
out[0] = S_BASE64CHAR[i >> 2];
|
||||
out[1] = S_BASE64CHAR[i << 4 & 63];
|
||||
out[2] = '=';
|
||||
out[3] = '=';
|
||||
writer.write(out, 0, 4);
|
||||
} else if (rest == 2) {
|
||||
i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255);
|
||||
out[0] = S_BASE64CHAR[i >> 10];
|
||||
out[1] = S_BASE64CHAR[i >> 4 & 63];
|
||||
out[2] = S_BASE64CHAR[i << 2 & 63];
|
||||
out[3] = '=';
|
||||
writer.write(out, 0, 4);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
int i;
|
||||
for (i = 0; i < S_DECODETABLE.length; ++i) {
|
||||
S_DECODETABLE[i] = 127;
|
||||
}
|
||||
|
||||
for (i = 0; i < S_BASE64CHAR.length; ++i) {
|
||||
S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static byte[] decodeByte(String data) {
|
||||
|
||||
char[] ibuf = new char[4];
|
||||
int ibufcount = 0;
|
||||
byte[] obuf = new byte[data.length() / 4 * 3 + 3];
|
||||
int obufcount = 0;
|
||||
for (int i = 0; i < data.length(); i++) {
|
||||
char ch = data.charAt(i);
|
||||
if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
|
||||
ibuf[ibufcount++] = ch;
|
||||
if (ibufcount == ibuf.length) {
|
||||
ibufcount = 0;
|
||||
obufcount += decode0(ibuf, obuf, obufcount);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obufcount == obuf.length) {
|
||||
return obuf;
|
||||
}
|
||||
byte[] ret = new byte[obufcount];
|
||||
System.arraycopy(obuf, 0, ret, 0, obufcount);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* @(#) FillTemplateHelper
|
||||
* 版权声明 网宿科技, 版权所有 违者必究
|
||||
*
|
||||
* <br> Copyright: Copyright (c) 2018
|
||||
* <br> Company:网宿科技
|
||||
* <br> @author Administrator
|
||||
* <br> @description 功能描述
|
||||
* <br> 2018-11-13 20:19:49
|
||||
*/
|
||||
|
||||
package util.itext;
|
||||
|
||||
import com.itextpdf.text.*;
|
||||
import com.itextpdf.text.pdf.*;
|
||||
import com.itextpdf.tool.xml.ElementList;
|
||||
import com.itextpdf.tool.xml.XMLWorker;
|
||||
import com.itextpdf.tool.xml.XMLWorkerHelper;
|
||||
import com.itextpdf.tool.xml.css.CssFile;
|
||||
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
|
||||
import com.itextpdf.tool.xml.html.TagProcessorFactory;
|
||||
import com.itextpdf.tool.xml.parser.XMLParser;
|
||||
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
|
||||
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
|
||||
import com.itextpdf.tool.xml.pipeline.end.ElementHandlerPipeline;
|
||||
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
|
||||
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* @author iText
|
||||
*/
|
||||
public class FillTemplateHelper extends PdfPageEventHelper {
|
||||
|
||||
// initialized in constructor
|
||||
protected PdfReader reader;
|
||||
protected Rectangle pageSize;
|
||||
protected Rectangle body;
|
||||
protected float mLeft, mRight, mTop, mBottom;
|
||||
protected Rectangle to;
|
||||
protected Rectangle from;
|
||||
protected Rectangle date;
|
||||
protected Rectangle footer;
|
||||
protected BaseFont basefont;
|
||||
protected Font font;
|
||||
// initialized with setter
|
||||
protected String sender = "";
|
||||
protected String receiver = "";
|
||||
// initialized upon opening the document
|
||||
protected PdfTemplate background;
|
||||
protected PdfTemplate total;
|
||||
|
||||
public FillTemplateHelper(String stationery) throws IOException, DocumentException {
|
||||
reader = new PdfReader(stationery);
|
||||
AcroFields fields = reader.getAcroFields();
|
||||
pageSize = reader.getPageSize(1);
|
||||
body = fields.getFieldPositions("body").get(0).position;
|
||||
mLeft = body.getLeft() - pageSize.getLeft();
|
||||
mRight = pageSize.getRight() - body.getRight();
|
||||
mTop = pageSize.getTop() - body.getTop();
|
||||
mBottom = body.getBottom() - pageSize.getBottom();
|
||||
footer = fields.getFieldPositions("footer").get(0).position;
|
||||
basefont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
|
||||
font = new Font(basefont, 12);
|
||||
|
||||
}
|
||||
|
||||
public static ElementList parseHtml(String content, String style, TagProcessorFactory tagProcessors) throws IOException {
|
||||
// CSS
|
||||
CSSResolver cssResolver = new StyleAttrCSSResolver();
|
||||
CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream(style));
|
||||
cssResolver.addCss(cssFile);
|
||||
// HTML
|
||||
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
|
||||
htmlContext.setTagFactory(tagProcessors);
|
||||
htmlContext.autoBookmark(false);
|
||||
// Pipelines
|
||||
ElementList elements = new ElementList();
|
||||
ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
|
||||
HtmlPipeline html = new HtmlPipeline(htmlContext, end);
|
||||
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
|
||||
// XML Worker
|
||||
XMLWorker worker = new XMLWorker(css, true);
|
||||
XMLParser p = new XMLParser(worker);
|
||||
p.parse(new FileInputStream(content), Charset.forName("utf8"));
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static ElementList parseHtmlContent(String content, String style, TagProcessorFactory tagProcessors) throws IOException {
|
||||
// CSS
|
||||
CSSResolver cssResolver = new StyleAttrCSSResolver();
|
||||
CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream(style));
|
||||
cssResolver.addCss(cssFile);
|
||||
// HTML
|
||||
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
|
||||
htmlContext.setTagFactory(tagProcessors);
|
||||
htmlContext.autoBookmark(false);
|
||||
// Pipelines
|
||||
ElementList elements = new ElementList();
|
||||
ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
|
||||
HtmlPipeline html = new HtmlPipeline(htmlContext, end);
|
||||
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
|
||||
// XML Worker
|
||||
XMLWorker worker = new XMLWorker(css, true);
|
||||
XMLParser p = new XMLParser(worker);
|
||||
try {
|
||||
p.parse(getStringStream(content), Charset.forName("utf8"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static InputStream getStringStream(String sInputString) {
|
||||
if (sInputString != null && !sInputString.trim().equals("")) {
|
||||
try {
|
||||
ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(sInputString.getBytes("UTF-8"));
|
||||
return tInputStringStream;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSender(String sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public void setReceiver(String receiver) {
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
public Rectangle getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public float getmLeft() {
|
||||
return mLeft;
|
||||
}
|
||||
|
||||
public float getmRight() {
|
||||
return mRight;
|
||||
}
|
||||
|
||||
public float getmTop() {
|
||||
return mTop;
|
||||
}
|
||||
|
||||
public float getmBottom() {
|
||||
return mBottom;
|
||||
}
|
||||
|
||||
public Rectangle getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpenDocument(PdfWriter writer, Document document) {
|
||||
background = writer.getImportedPage(reader, 1);
|
||||
total = writer.getDirectContent().createTemplate(30, 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndPage(PdfWriter writer, Document document) {
|
||||
PdfContentByte canvas = writer.getDirectContentUnder();
|
||||
// background
|
||||
canvas.addTemplate(background, 0, 0);
|
||||
try {
|
||||
ColumnText ct = new ColumnText(canvas);
|
||||
ct.setSimpleColumn(footer);
|
||||
ct.addText(new Chunk(" " + writer.getPageNumber(), font));
|
||||
ct.addText(new Chunk(Image.getInstance(total), 0, 0));
|
||||
ct.go();
|
||||
} catch (DocumentException e) {
|
||||
// can never happen, but if it does, we want to know!
|
||||
throw new ExceptionConverter(e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCloseDocument(PdfWriter writer, Document document) {
|
||||
// 关闭时可以知道总页数,写入页码
|
||||
String s = "/ " + (writer.getPageNumber());
|
||||
Phrase p = new Phrase(12, s, font);
|
||||
ColumnText.showTextAligned(total, Element.ALIGN_LEFT, p, 0.5f, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
|
||||
|
||||
package util.itext;
|
||||
|
||||
import com.itextpdf.text.*;
|
||||
import com.itextpdf.text.pdf.*;
|
||||
import com.itextpdf.tool.xml.ElementList;
|
||||
import com.itextpdf.tool.xml.html.Tags;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by huangzhijun on 2017/8/22.
|
||||
* itext 用于生成pdf的工具类
|
||||
*/
|
||||
public class PDFUtils {
|
||||
/**
|
||||
* 通过模板生成pdf文件
|
||||
*
|
||||
* @param templatePath 模板路径
|
||||
* @param resultPath 生成路径
|
||||
* @param cssPath css路径
|
||||
* @param content 生成pdf的内容
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void generalPDF(String templatePath, String resultPath, String cssPath, String content) throws Exception {
|
||||
// 读取模板
|
||||
FillTemplateHelper template = new FillTemplateHelper(templatePath);
|
||||
Document document = new Document(template.getPageSize(),
|
||||
template.getmLeft(), template.getmRight(), template.getmTop(), template.getmBottom());
|
||||
// 创建pdf写对象
|
||||
PdfWriter writer = null;
|
||||
FileOutputStream outputStream = new FileOutputStream(resultPath);
|
||||
try {
|
||||
writer = PdfWriter.getInstance(document, outputStream);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
writer.setPageEvent(template);
|
||||
//打开文件
|
||||
document.open();
|
||||
// 填充数据到文件中
|
||||
ElementList elements = FillTemplateHelper.parseHtmlContent(content, cssPath, Tags.getHtmlTagProcessorFactory());
|
||||
for (Element e : elements) {
|
||||
document.add(e);
|
||||
}
|
||||
writer.setPageEmpty(false);
|
||||
//关闭流操作
|
||||
document.close();
|
||||
writer.close();
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF盖章操作
|
||||
* 在PDF文档的最后一页盖章
|
||||
* @param RES 需要盖章的pdf文件地址
|
||||
* @param DEST 生成的新pdf文件地址
|
||||
* @param SEAL 印章图片的地址
|
||||
* @param company 落款名称及部门
|
||||
* @param dateName 落款时间名称
|
||||
* @throws DocumentException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void sealDocument(String RES, String DEST, String SEAL, String company, String dateName, String time) throws DocumentException, IOException {
|
||||
|
||||
PdfReader reader = new PdfReader(RES);
|
||||
int numberOfPages = reader.getNumberOfPages();
|
||||
Rectangle pageSize = reader.getPageSize(1);
|
||||
Document doc = new Document(pageSize);
|
||||
PdfWriter writer_ = PdfWriter.getInstance(doc, new FileOutputStream(DEST));
|
||||
// 打开文档
|
||||
doc.open();
|
||||
PdfContentByte cb = writer_.getDirectContent();
|
||||
for (int i = 0; i < numberOfPages; ) {
|
||||
{
|
||||
i++;
|
||||
//设置指定页的PagSize 包含Rotation(页面旋转度)
|
||||
// doc.setPageSize(reader.getPageSizeWithRotation(i));
|
||||
//创建一个新的页面,需要注意的调用NewPage() ,PdfContentByte cb 对象会默认清空
|
||||
doc.newPage();
|
||||
// //获取指定页面的旋转度
|
||||
// int rotation = reader.getPageRotation(i);
|
||||
//获取加载PDF的指定页内容
|
||||
PdfImportedPage page1 = writer_.getImportedPage(reader, i);
|
||||
|
||||
//添加内容页到新的页面,并更加旋转度设置对应的旋转
|
||||
/* switch (rotation) {
|
||||
case 90:
|
||||
cb.addTemplate(page1, 0, -1, 1, 0, 0, reader.getPageSizeWithRotation(i).getHeight());
|
||||
break;
|
||||
case 180:
|
||||
cb.addTemplate(page1, -1, 0, 0, -1, reader.getPageSizeWithRotation(i).getWidth(), reader.getPageSizeWithRotation(i).getHeight());
|
||||
break;
|
||||
case 270:
|
||||
cb.addTemplate(page1, 0, 1, -1, 0, reader.getPageSizeWithRotation(i).getWidth(), 0);
|
||||
break;
|
||||
default:
|
||||
cb.addTemplate(page1, 1, 0, 0, 1, 0, 0);//等同于 cb.AddTemplate(page1, 0,0)
|
||||
break;
|
||||
}*/
|
||||
cb.addTemplate(page1, 0, 0);
|
||||
|
||||
if (i == numberOfPages)//如果是最后一页加入指定的图片
|
||||
{
|
||||
//创建一个图片对象
|
||||
Image img = Image.getInstance(SEAL);
|
||||
//设置图片的指定大小
|
||||
//img.ScaleToFit(140F, 320F);
|
||||
//按比例缩放
|
||||
img.scalePercent(100);
|
||||
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
|
||||
cb.beginText();
|
||||
//设置字体 大小
|
||||
cb.setFontAndSize(bf, 13);
|
||||
//指定添加文字的绝对位置
|
||||
cb.setTextMatrix(350, 75);
|
||||
//增加文本
|
||||
cb.showText(company);
|
||||
//结束
|
||||
cb.endText();
|
||||
cb.beginText();
|
||||
//设置字体 大小
|
||||
cb.setFontAndSize(bf, 13);
|
||||
//指定添加文字的绝对位置
|
||||
cb.setTextMatrix(350, 55);
|
||||
if (org.apache.commons.lang3.StringUtils.isBlank(time)) {
|
||||
Date date = new Date();
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
time = format.format(date);
|
||||
}
|
||||
//增加文本
|
||||
cb.showText(dateName + ":" + time);
|
||||
//结束
|
||||
cb.endText();
|
||||
//把图片增加到内容页的指定位子 b width c height e bottom f left
|
||||
// use addImage(image, image_width, 0, 0, image_height, x, y)
|
||||
cb.addImage(img, 130, 0, 0, 130, 400, 55);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("盖章成功");
|
||||
doc.close();
|
||||
writer_.close();
|
||||
reader.close();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将页面传过来的内容重新组装为html
|
||||
* @param content
|
||||
* @return
|
||||
*/
|
||||
public String transToHtml(String content) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("<html>");
|
||||
sb.append("<head>");
|
||||
sb.append("<meta charset=\"UTF-8\" />");
|
||||
sb.append("</head>");
|
||||
sb.append("<body style='font-family:SimSun;'>");
|
||||
sb.append("<div class=\"executed-report\">");
|
||||
sb.append("<div class=\"report-box clearfix\">");
|
||||
sb.append(content);
|
||||
sb.append("</div>");
|
||||
sb.append("</div>");
|
||||
sb.append("</body>");
|
||||
sb.append("</html>");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
|
||||
package util.time;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import model.fullFillTime.OriginTimeValue;
|
||||
import model.fullFillTime.TargetTimeValue;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 补时间点工具类
|
||||
* 之前在ws上班的时候,处理图标数据会遇到某些点没有数据的情况,就需要对这些时间点进行补点处理
|
||||
*
|
||||
* @author huangzj
|
||||
* @date 2018-11-23 22:43:36
|
||||
*/
|
||||
public enum FillFullTimeValueUtil {
|
||||
/**
|
||||
* 分钟粒度
|
||||
*/
|
||||
MINUTE {
|
||||
@Override
|
||||
public List<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval,
|
||||
List<OriginTimeValue> originTimeValues, TimeZone timeZone) {
|
||||
//Myview 向前聚合,返回前XX秒为最开始计数时间
|
||||
Instant firstInstant = toInstant(startDate, timeZone);
|
||||
Instant finalInstant = toInstant(endDate, timeZone);
|
||||
//补时间点--规则一样,间隔转换成秒
|
||||
return fullFillRule(originTimeValues, firstInstant, finalInstant, timeInterval * 60);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 小时粒度
|
||||
*/
|
||||
HOUR {
|
||||
@Override
|
||||
public List<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval,
|
||||
List<OriginTimeValue> originTimeValues, TimeZone timeZone) {
|
||||
Instant firstInstant = toInstant(startDate, timeZone);
|
||||
Instant finalInstant = toInstant(endDate, timeZone);
|
||||
//补时间点--规则一样
|
||||
return fullFillRule(originTimeValues, firstInstant, finalInstant, timeInterval * 60 * 60);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 天粒度
|
||||
*/
|
||||
DAY {
|
||||
@Override
|
||||
public List<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval,
|
||||
List<OriginTimeValue> originTimeValues, TimeZone timeZone) {
|
||||
//区别,把时间转成天
|
||||
Instant firstInstant = toInstant(LocalDateTime.of(startDate.toLocalDate(), LocalTime.of(0, 0, 0)), timeZone);
|
||||
Instant finalInstant = toInstant(LocalDateTime.of(endDate.toLocalDate(), LocalTime.of(0, 0, 0)), timeZone);
|
||||
//补时间点--规则一样
|
||||
return fullFillRule(originTimeValues, firstInstant, finalInstant, timeInterval * 60 * 60 * 24);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 抽象方法,实现补充时间点
|
||||
* @param startDate 开始时间 格式如:yyyy-MM-dd 00:00:00
|
||||
* @param endDate 结束时间:格式如:yyyy-MM-dd 23:59:59
|
||||
* @param timeInterval 数据采集粒度,单位:分钟、小时、天
|
||||
* @param originTimeValues 缺少时间点对象(统一处理成long、long)
|
||||
* @param timeZone 时区
|
||||
* @return 补时间点后对象,没有补null
|
||||
*/
|
||||
public abstract List<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate,
|
||||
int timeInterval, List<OriginTimeValue> originTimeValues, TimeZone timeZone);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dateTime 时间
|
||||
* @param timeZone 时区
|
||||
* @return Instant,和TimeStamp类似
|
||||
*/
|
||||
private static Instant toInstant(LocalDateTime dateTime, TimeZone timeZone) {
|
||||
return dateTime.atZone(timeZone.toZoneId())
|
||||
.toInstant();
|
||||
}
|
||||
|
||||
|
||||
private static List<TargetTimeValue> fullFillRule(List<OriginTimeValue> originTimeValues, Instant firstInstant, Instant finalInstant,
|
||||
int seconds) {
|
||||
//转换为Time-value形式的map
|
||||
if (CollectionUtils.isEmpty(originTimeValues)) {
|
||||
originTimeValues = Lists.newArrayList();
|
||||
}
|
||||
Map<Long, Long> timeValueMap = originTimeValues.stream().collect(Collectors.toMap(OriginTimeValue::getTime,
|
||||
OriginTimeValue::getValue));
|
||||
final List<TargetTimeValue> resultList = new ArrayList<>();
|
||||
|
||||
Instant cursorInstant = firstInstant;
|
||||
//循环按照时间粒度补充时间点。
|
||||
while (cursorInstant.isBefore(finalInstant) || cursorInstant.equals(finalInstant)) {
|
||||
long epochSecond = cursorInstant.getEpochSecond();
|
||||
TargetTimeValue timeValueInRule = new TargetTimeValue();
|
||||
timeValueInRule.setValue(timeValueMap.getOrDefault(epochSecond, null));
|
||||
timeValueInRule.setTime(epochSecond);
|
||||
resultList.add(timeValueInRule);
|
||||
|
||||
//移动到下一个数据点
|
||||
cursorInstant = cursorInstant.plusSeconds(seconds);
|
||||
}
|
||||
//按时间排序,最新的排在最后面
|
||||
return resultList.parallelStream()
|
||||
.sorted(Comparator.comparing(TargetTimeValue::getTime))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
[${identification}!]
|
||||
${time}!:${platform}!:
|
||||
${statistic}!详细信息请查看审计子系统,并及时处理
|
||||
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>富文本编辑器测试</title>
|
||||
<meta charset="UTF-8">
|
||||
<style type="text/css">
|
||||
.toolbar {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.text {
|
||||
border: 1px solid #ccc;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
/* table 样式 */
|
||||
table {
|
||||
border-top: 1px solid #ccc;
|
||||
border-left: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table td,
|
||||
table th {
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
table th {
|
||||
border-bottom: 2px solid #ccc;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* blockquote 样式 */
|
||||
blockquote {
|
||||
display: block;
|
||||
border-left: 8px solid #d0e5f2;
|
||||
padding: 5px 10px;
|
||||
margin: 10px 0;
|
||||
line-height: 1.4;
|
||||
font-size: 100%;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
/* code 样式 */
|
||||
code {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 3px;
|
||||
padding: 3px 5px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ul ol 样式 */
|
||||
ul, ol {
|
||||
margin: 10px 0 10px 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h3>卧槽。配置这么简单???</h3>
|
||||
<div id="editor">
|
||||
<p>欢迎使用 <b>wangEditor</b> 富文本编辑器</p>
|
||||
</div>
|
||||
<!-- 注意, 只需要引用 JS,无需引用任何 CSS !!!-->
|
||||
<br><br><br>
|
||||
<input type="button" value="提交富文本信息" id="sendData">
|
||||
<input type="button" value="获取数据和展示" id="getData">
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script type="text/javascript" src="../js/wangEdit/wangEditor.js"></script>
|
||||
<script type="text/javascript" src="../js/jquery/jquery.js"></script>
|
||||
<script type="text/javascript" src="../js/config.js"></script>
|
||||
<script type="text/javascript" src="../js/module/myjs/edit.js"></script>
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user