cron,quartz-scheduler,Stream流HTTPS
10 * * * * ? 每分钟第10秒执行 30 10 1 * * ? 每天1点10分30秒触发任务 "30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务 "15/5 * * * * ?" 每分钟的每15秒开始触发,每隔5秒触发一次 秒、分、小时、日期、月份、星期和年份
@Controller @RequestMapping("/hello3") @ResponseBody 直接响应json格式
OutputStream 输出流,用来write写的,把数据写进入
如果是文件输出流,结果就是把数据写入文件
如果是HttpURLConnection输出流,结果就是把数据写入http发送数据
InputStream 输入流,用来read读取的,把数据读出来
如果是文件输入流,结果就是把数据从文件中读取到字节、字符数组中
如果是HttpURLConnection输入流,结果就是读取数据接收http数据
字符流(一次可以处理一个缓冲区)一次操作比字节流(一次一个字节)效率高。
字节流通常用于处理二进制数据,不支持直接读写字符;字符流通常用于处理文本数据
在读写文件需要对文本内容进行处理:按行处理、比较特定字符的时候一般会选择字符流;仅仅读写文件,不处理内容,一般选择字节流
https://ww.cnblogs.com/liangbaolong/p/12880487.html
public static byte[] readFromFile(){ String path = "test.txt"; byte[] data = new byte[10]; char[] chars = new char[10]; try { FileInputStream fileInputStream = new FileInputStream(new File(path)); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); Reader reader = new BufferedReader(inputStreamReader); FileOutputStream fileOutputStream = new FileOutputStream(new File("test2.txt")); int b = 0; while ((b = fileInputStream.read(data)) >=0){ fileOutputStream.write(data,0,b); data = new byte[10]; } fileOutputStream.flush(); fileOutputStream.close(); fileInputStream.close(); FileWriter fw = new FileWriter(new File("test2.txt")); //文件输出流 (字符流) int b = 0; while ( (b = reader.read(chars)) >= 0) { System.out.println(b); fw.write(chars,0,b);//此写法可以防止最后一组数据填不满,把null数据也写到fw里 // fw.write(chars); chars = new char[10]; } fw.flush(); reader.close(); fw.close(); } catch (Exception e) { e.printStackTrace(); } return null; }
从目标文件或资源读取 URL u = new URL(url); UrlResource ur = new UrlResource(u); 输入读: InputStream in = ur.getInputStream(); //字节输入流 例如从url资源获取 FileInputStream in = new FileInputStream(new File("D:/test.txt")); 文件输入流(字节流) FileReader fr = new FileReader(new File("D:/test.txt")); 文件输入流(字符流) InputStreamReader isr = new InputStreamReader(in,"gbk"); 字符输入流 Reader read = new BufferedReader(isr); 字符输入流 输出写: OutputStream outStream = response.getOutputStream(); 字节输出流 例如从http响应获取 ByteArrayOutputStream bao = new ByteArrayOutputStream(); 字节输出流 FileOutputStream fos = new FileOutputStream(file); 文件输出流 (字节流) FileWriter fw = new FileWriter(new File("D:/test2.txt")); 文件输出流 (字符流) OutputStreamWriter out = new OutputStreamWriter(fos); 字符输出流 Writer wr = new BufferedWriter(out); 字符输出流 字节流: while((i=in.read(b))>=0){//从输入流读取到字节数组 i是返回的读到b的字节个数 返回-1表示已读完 bao.write(b);//字节数组写入输出流 b = new byte[1024]; } 字符流: while((c= read.read(ch))>=0){ //从输入流读取字符数组 //out.write(ch,0, c); //字符数组写入输出流 wr.write(ch); ch = new char[5]; } wr.flush(); wr.close(); 操作字符流涉及字符编码,字节流不涉及 基于字节流的stream: DataOutputStream----DataInputStream: FileOutputStream-----FileInputStream: 基于字符流的stream(典型的以write和reader来标识的): FileWriter---FileReader: StringWriter---StringReader: BufferedWriter--BufferedReader
@RequestMapping("/hello2") public void hello2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; MultipartFile multipartFile = multipartRequest.getFile("file"); String imageNameOriginal = multipartFile.getOriginalFilename(); System.out.println("uploadCostomerImg imageNameOriginal:"+imageNameOriginal); String[] ss = imageNameOriginal.split("\\\\"); File fileupload = new File("F:\\study-idea\\space\\xmhAID\\file\\"+ss[ss.length-1]); //读取图片 multipartFile.transferTo(fileupload);//读取流到本地文件 System.out.println("uploadCostomerImg 图片地址:"+ fileupload); } ## 是设置单个文件的大小 spring.http.multipart.maxFileSize=300Mb 是设置单次请求的文件的总大小 spring.http.multipart.maxRequestSize=300Mb <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <form action="http://192.168.206.1:9990/hello2" enctype="multipart/form-data" method="post"> 上传文件:<input type="file" name="file"><br/> <input type="submit" value="提交"> </form>
quartz-scheduler
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.6.8</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.3</version> </dependency> @Service public class QuartzServiceImpl implements IQuartzService { @Autowired Scheduler scheduler; @Override public void addJob() { ScheduleJob job = new ScheduleJob(); job.setJobName("job1"); job.setCronExpression("0/5 * * * * ?"); try { //创建触发器 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity(job.getJobName()) .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression())) .startNow() .build(); //创建任务 JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class) .withIdentity(job.getJobName()).build(); //QuartzFactory传入调度的参数 jobDetail.getJobDataMap().put("scheduleJob",job); log.info("addJob****1******"+job.getJobName()); //调度作业 JobKey jobKey = new JobKey(job.getJobName()); scheduler.deleteJob(jobKey); scheduler.scheduleJob(jobDetail,trigger); log.info("addJob****2******"+job.getJobName()); } catch (Exception e){ throw new RuntimeException(e); } } @Override public void operateJob(JobOperateEnum jobOperateEnum, String jobName) throws SchedulerException { JobKey jobKey = new JobKey(jobName); JobDetail jobDetail = scheduler.getJobDetail(jobKey); if (jobDetail == null){ throw new SchedulerException("此定时任务不存在"); } //任务操作 switch (jobOperateEnum){ case START: //启动 scheduler.resumeJob(jobKey); break; case PAUSE: //暂停 scheduler.pauseJob(jobKey); break; case DELETE: //删除 scheduler.deleteJob(jobKey); break; default: break; } } @Override public void startAllJob() throws SchedulerException { scheduler.start(); } @Override public void pauseAllJob() throws SchedulerException { scheduler.standby(); } public class QuartzJob implements Job { @SneakyThrows @Override public void execute(JobExecutionContext jobExecutionContext) { //获取调度数据 ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob"); //获取对应的bean try { log.info("开始执行任务xxxx==》{}",scheduleJob.getJobName()); //利用反射执行对应方法 // Class<?> jobClass = Class.forName(scheduleJob.getBeanName()); // Method method = jobClass.getMethod(scheduleJob.getMethodName(), JobExecutionContext.class); // method.invoke(jobClass.newInstance(), jobExecutionContext); } catch (Exception e) { log.error("任务调度工厂方法执行异常==》{}",e.getMessage()); } } } @Configuration public class QuartzConfig { @Autowired private JobFactory jobFactory; //创建调度器工厂 @Bean public SchedulerFactoryBean schedulerFactoryBean(){ SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setAutoStartup(true); //覆盖已存在的任务 //schedulerFactoryBean.setOverwriteExistingJobs(true); //注意这里是重点 // schedulerFactoryBean.setJobFactory(jobFactory); //这样当spring关闭时,会等待所有已经启动的quartz job结束后spring才能完全shutdown。 schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true); //服务启动20秒后启动定时任务 schedulerFactoryBean.setStartupDelay(20); return schedulerFactoryBean; } /** * 创建scheduler * @return Scheduler */ @Bean(name = "scheduler") public Scheduler scheduler(){ return schedulerFactoryBean().getScheduler(); } /** * quartz初始化监听器 用处: 服务启动时执行任务 ,非必要配置 */ // @Bean // public QuartzInitializerListener executorListener() { // return new QuartzInitializerListener(); // } } /** * @ClassName JobFactory * @Description 创建job 实例工厂,解决spring注入问题,如果使用默认会导致spring的@Autowired 无法注入问题 * @Author chaic * @Date 2020/6/8 12:02 * @Version 1.0 */ @Component public class JobFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //调用父类的方法 Object jobInstance = super.createJobInstance(bundle); //进行注入 capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
quartz集群模式
quartz-scheduler http://www.quartz-scheduler.org 2.2.3 官网下载sql脚本 \quartz-2.2.3-distribution\quartz-2.2.3\docs\dbTables quartz https://zhuanlan.zhihu.com/p/684740530 修改任务 public void rescheduleJob(Scheduler scheduler, String triggerName, String triggerGroup, String newCronExpression) throws SchedulerException { TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup); // 获取旧的触发器 CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 定义新的触发器,使用新的cron表达式 Trigger newTrigger = oldTrigger.getTriggerBuilder() .withSchedule(CronScheduleBuilder.cronSchedule(newCronExpression)) .build(); // 重新调度作业 scheduler.rescheduleJob(triggerKey, newTrigger); } 在集群模式下,Quartz通过数据库锁来确保同一个任务不会被多个节点同时执行。当一个调度器实例尝试执行一个任务时,它会先在数据库中对该任务加锁。如果加锁成功,该实例就会执行任务;否则,意味着有其他实例已经在执行该任务,当前实例就会放弃执行。 org.quartz.scheduler.instanceName: MyClusteredScheduler org.quartz.scheduler.instanceId: AUTO org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.useProperties: false org.quartz.jobStore.dataSource: myDS org.quartz.jobStore.tablePrefix: QRTZ_ org.quartz.jobStore.isClustered: true org.quartz.dataSource.myDS.driver: com.mysql.jdbc.Driver org.quartz.dataSource.myDS.URL: jdbc:mysql://x.x.x.x:3306/a_test?useSSL=false org.quartz.dataSource.myDS.user: x org.quartz.dataSource.myDS.password: xx org.quartz.dataSource.myDS.maxConnections: 5 org.quartz.threadPool.threadConut:20 线程数 org.quartz.threadPool.threadPriority:5 线程优先级 //创建调度器工厂 @Bean public SchedulerFactoryBean schedulerFactoryBean(){ //追加如下代码 File file ; InputStream inputStream = null; Resource resource= null; try { // file = ResourceUtils.getFile("classpath:quartz.properties");//在linux环境中无法读 // inputStream = new FileInputStream(file); // resource = new InputStreamResource(inputStream); // resource = new ClassPathResource("quartz.properties"); resource = resourceLoader.getResource("classpath:quartz.properties"); } catch (Exception e) { e.printStackTrace(); } schedulerFactoryBean.setConfigLocation(resource); return schedulerFactoryBean; }
//去掉如下配置 /** * quartz初始化监听器 */ // @Bean // public QuartzInitializerListener executorListener() { // return new QuartzInitializerListener(); // } 可增加如下配置 schedulerFactoryBean.setTaskExecutor(taskExecutor()); @Bean public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(500); return executor; }
https服务器搭建
https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter2_7.shtml
public static void main(String[] args) { //传入null请求接收方会报错 String s1 = httpReq("http://localhost:9098/insurance/insuranceAward/insuranceSport2.json?userId=123&policyNo=321","123xxxxxxmmmmmmm"); System.out.println("result:"+s1); } @RequestMapping(value = "/insuranceSport2") @ResponseBody public ResultVO<String> test2(@Valid MyRequest request, HttpServletRequest req, HttpServletResponse res,@RequestBody String jsonString) { ResultVO rs = new ResultVO(); System.out.println(request); System.out.println(jsonString); return rs; } public static String httpReq(String url, String params) { StringBuffer bufferRes = new StringBuffer(); HttpURLConnection conn = null; InputStream in = null; try { URL realUrl = new URL(url); conn = (HttpURLConnection) realUrl .openConnection(); // 连接超时 conn.setConnectTimeout(30000); // 读取超时 --服务器响应比较慢,增大时间 conn.setReadTimeout(30000); HttpURLConnection.setFollowRedirects(true); // 请求方式 conn.setRequestMethod("GET"); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); if (StringUtils.isNotBlank(params)) { conn.setRequestProperty("CONTENT_LENGTH","" + params.length()); } // conn.setRequestProperty("Accept-Charset", "UTF-8"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0"); conn.setRequestProperty("Referer", "https://api.weixin.qq.com/"); // 发送请求参数 if (params != null) { OutputStream out = conn.getOutputStream(); out.write(params.getBytes("UTF-8")); out.flush(); out.close(); out = null; } //接收返回 public static void main(String[] args) { //传入null请求接收方会报错 String s1 = httpReq("http://localhost:9098/insurance/insuranceAward/insuranceSport2.json?userId=123&policyNo=321","123xxxxxxmmmmmmm"); System.out.println("result:"+s1); } @RequestMapping(value = "/insuranceSport2") @ResponseBody public ResultVO<String> test2(@Valid MyRequest request, HttpServletRequest req, HttpServletResponse res,@RequestBody String jsonString) { ResultVO rs = new ResultVO(); System.out.println(request); System.out.println(jsonString); return rs; } public static String httpReq(String url, String params) { StringBuffer bufferRes = new StringBuffer(); HttpURLConnection conn = null; InputStream in = null; try { URL realUrl = new URL(url); conn = (HttpURLConnection) realUrl .openConnection(); // 连接超时 conn.setConnectTimeout(30000); // 读取超时 --服务器响应比较慢,增大时间 conn.setReadTimeout(30000); HttpURLConnection.setFollowRedirects(true); // 请求方式 conn.setRequestMethod("GET"); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); if (StringUtils.isNotBlank(params)) { conn.setRequestProperty("CONTENT_LENGTH","" + params.length()); } // conn.setRequestProperty("Accept-Charset", "UTF-8"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0"); conn.setRequestProperty("Referer", "https://api.weixin.qq.com/"); // 发送请求参数 if (params != null) { OutputStream out = conn.getOutputStream(); out.write(params.getBytes("UTF-8")); out.flush(); out.close(); out = null; } //接收返回 in = conn.getInputStream(); BufferedReader read = new BufferedReader(new InputStreamReader(in,"UTF-8")); String valueString = null; while ((valueString = read.readLine()) != null) { bufferRes.append(valueString); } in.close(); read.close(); in = null; read = null; if (conn != null) { conn.disconnect(); } } catch (Exception e) { LOGGER.error("http请求微信服务异常", e); } finally{ conn = null; in = null; } return bufferRes.toString(); } in = conn.getInputStream(); BufferedReader read = new BufferedReader(new InputStreamReader(in,"UTF-8")); String valueString = null; while ((valueString = read.readLine()) != null) { bufferRes.append(valueString); } in.close(); read.close(); in = null; read = null; if (conn != null) { conn.disconnect(); } } catch (Exception e) { LOGGER.error("http请求微信服务异常", e); } finally{ conn = null; in = null; } return bufferRes.toString(); }
// https public static String httpRequest(String requestUrl, String outputStr) { StringBuffer buffer = new StringBuffer(); try { TrustManager[] tm = { new TrustAnyTrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url .openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod("POST"); if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "UTF-8"); BufferedReader bufferedReader = new BufferedReader( inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); return buffer.toString(); } catch (Exception e) { LOGGER.error("WeixinHttpUtil-->httpRequest error"+e.getMessage(),e); } return ""; }