Alfred 精确计算器
扩展 Alfred 原生计算器能力
Spring 中的跨域问题
项目做前后端分离,遇到了一个很常见的问题:跨域。想着每次遇到都要搜索解决,而且搜到的文章给出的解决方案又千奇百怪,不一定合适,于是萌生了总结一下的想法。 问题由来跨站 HTTP 请求(Cross-site HTTP Request)是指发起请求的资源所在的 domain 与该请求所指向的 domain 不同的 HTTP 请求。比如,域名 abc(www.abc.com) 的某个标签引用了域名 cde(www.cde.com) 的某资源,域名 abc 的 Web 应用就会导致浏览器发起一个跨站 HTTP 请求。 这种方式极大地方便了 Web 开发,然而,出于安全考虑(主要是防范 csrf),浏览器会限制从脚本内发起的跨源 HTTP 请求。例如 XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源。 然而如果我们在本地开发前后端分离程序,前端请求本机上的后端 API 却由于浏览器限制而请求失败,十分不便。 CORS跨域资源共享(CORS)机制允许 Web...
Maven 中的 Scope
Maven 中 scope 的取值一共有 compile、test、runtime、provided、system 这几种,其实没有必要专门写一篇博客来讲。但是最近遇到了一个相关的坑,其实也不能说是坑,主要原因是自己对这些东西一知半解,所以还是有必要深究一下。 compilecompile 是默认的 scope,即不显式声明条件下 scope 就是 compile。compile 表示该依赖需要参与项目编译、测试、运行等所有步骤中,是最强的依赖,打包时通常需要包含进去。 testtest 表示依赖项目仅仅参与测试相关的工作,包含测试代码的编译、执行,但是原项目的编译、运行均不参与其中。 runtimeruntime 表示依赖不会参与项目的编译,不过会参与到后续的测试与运行环节中。与 compile 相比只是少了编译阶段,那为什么要提供这个 scope 呢? StackOverflow 上有一个经典回答:https://stackoverflow.com/a/12273576/7944150。简单翻译下,声明 scope 为 runtime...
聊聊延时任务队列
延时队列,顾名思义,是为了让一些任务不立即执行,放到队列里面等到特定时间后再执行。常用的场景有: 订单一直处于未支付状态,需要及时关闭订单,并退还库存 用户通过遥控设备控制智能设备在指定时间进行工作 eFuture 中未来邮件需要在用户指定的时间点发送 eFuture 是我最近刚完成的一个项目,主要目的是提供“未来邮件”的服务。其中,邮件需要被存储并且需要在特定时间点发送。于是我就需要一个延时队列来保存发信任务,并在指定时间由程序消费任务,从而发送邮件。 对于 eFuture 来说,有两件事是最重要的: 未来邮件在延时任务队列中保存,并且不会因为系统故障(如突发停机)而丢失 未来邮件需要在指定日期被取出并消费掉(发送出) 这两点需求意味着,提供延时任务的组件需要具备容灾能力,所以常用的 Java 内部的实现就不行了(虽说我也没用 Java 来写这个项目)。一番搜索之后,发现常用的实现有两个符合我的要求:RabbitMQ 与 Redis。 RabbitMQRabbitMQ 本身并没有直接支持延时队列功能,但是我们可以通过 RabbitMQ...
利用 Travis CI 自动测试、部署 Java Web 项目到 Tomcat
上一个项目的部署测试流程是:本地写完,本地测试,打包为 war 上传到服务器,服务器部署到 Tomcat 指定目录下,重启 Tomcat。这一套流程下来少说十分钟,而且如果刚上传完发现有 bug 的话,还要本地改完重新再来一遍。 重复这样的过程让人心神俱疲,好在现在已经有成熟的解决方案如 Travis CI、Jenkins等,今天我们就尝试着在 Java Web 项目中运用 Travis CI 来自动测试、部署、重启。 Travis CI 是软件开发领域一个在线的、分布式的持续集成服务,它与 GitHub 的协作相当紧密,并且对开源项目免费。 注册配置 Travis到 Travis 的官网 https://travis-ci.org 注册登录,其实是用 GitHub 做第三方授权登录,十分简单。 注册成功后进入个人 Profile 页,选择一个需要集成 Travis CI 的项目,开启 Build 即可。 创建项目本文我们以一个简单的 Spring Boot...
编译原理之 Chomsky 文法的判断 —— Java 实现
文法的定义和记号 $$ G = (V_N, V_T, P, S) \qquad (V_N \cap V_T = \varnothing, V_N \cup V_T = V) $$ 是 N.Chomsky 在 1956 年描述形式语言时首先给出的。同时,Chomsky 还对产生式的形式给以不同的限制而定义了四类基本的文法,分别称之为 0 型文法,1 型文法,2 型文法和 3 型文法。 明确定义 0 型文法:对任一产生式 $\alpha \to \beta$,都有 $\alpha \in V^+, \quad \beta \in V^*$ 1 型文法:对任一产生式 $\alpha \to \beta$,都有 $\mid\beta\mid \ge \mid\alpha\mid, \quad \alpha,\beta \in V^+$,仅仅 $\alpha \to \epsilon$ 除外 2 型文法:对任一产生式 $A \to \beta$,都有 $A \in V_N, \quad \beta \in V^+$ 3 型文法:任一产生式都形如 $A...
Spring Boot 项目打包并部署到 Tomcat、Tomcat 同时部署多应用
Spring Boot 项目开发完毕后,需要部署到 tomcat 服务器下,鉴于经常忘记部署流程,特地写了一篇博客来记录。 打包为 war修改 packaging基于 Intellij IDEA 构建项目有一个好处是大多数东西它已经自动帮你设置好了,不需要太多修改的地方。 修改 pom.xml 中的打包格式: <packaging>jar</packaging> –> <packaging>war</packaging> 插件与组件有的博客中提到了 build 组件和 tomcat 插件(pom.xml 中),在 Intellij IDEA 生成的 pom 中并没有这些东西,所以可以直接跳过。 注册启动类修改 Application 类,继承 SpringBootServletInitializer 并重写 configure 方法,在方法中注册启动类: 1234567891011@SpringBootApplicationpublic class Application extends...
Spring Boot 集成 Shiro 权限管理与密码加盐加密存储
在 Spring 中,流行的涉及权限管理的框架有两个:Spring Security 和 Apache Shiro。但是去了解一下 Spring Security 就知道,简单的权限管理根本用不到那么复杂的功能。在自己的项目中,我更倾向于使用简单明了的 Apache Shiro。 我们以最常见的用户、角色、权限关系做例子。一个用户有多个角色、一个角色有多个用户、一个角色有多个权限、一个权限有多个角色。即用户与角色、角色与权限是多对多关系。 引入 shiro-spring 包pom包依赖重要的是 shiro-spring 这个包。 12345678910111213141516171819202122<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency> ...
SpringBoot WebSocket 发送广播,Android 接收
WebSocketWebSocket 为客户端、浏览器和服务端提供了双工异步通信的功能,即客户端(浏览器、Android)可以向服务器发送消息,服务器端也可以向客户端发送消息。 WebSocket 是通过一个 socket 来实现双工异步通信能力的。但是直接使用 WebSocket 协议开发程序会十分繁琐,因此我们使用它的子协议 STOMP,它是一个更高级别的协议。STOMP 协议使用一个基于帧的格式来定义消息,与 HTTP 的 request 和 response 类似(具有类似于 @RequestMpping 的注解 @MessageMapping)。 Spring Boot 的支持Spring Boot 对内嵌的 Tomcat、Jetty 和 Undertow 使用 WebSocket 提供了支持。 Spring Boot 为 WebSocket 提供的 starter pom 是 spring-boot-starter-websocket。 服务器端使用 Intellij IDEA + maven 搭建。spring-boot-starter 选择...
Nginx 提供文件下载服务
有时候我们可能需要提供一些配置文件或安装包的下载链接,这种场景使用 CDN 有些杀鸡用牛刀,通过 Eginx 配置可以简单快速的提供功能。 Nginx 配置: 12345678910111213server { listen 80; server_name download.akise.app; root /path/to/download.akise.app; location / { index index.html; } location /app { default_type application/octet-stream; }} 文件夹配置: 12mkdir /path/to/download.akise.app/apptouch /path/to/download.akise.app/app/t.apk 浏览器访问 http://download.akise.app/app/t.apk 即会自动开始下载。