1什麼是springboot框架?
springboot是目前最流行的開箱即用的框架,該框架的目的是爲了幫助開發人員減化配置,提高開發人員的速度等等。具體自行百度,今天的主角可不是它,今天寫這遍文章的目的是整合scala語言在springboot當中。
2 什麼是scala語言?
相信從java8開始,大家就注意到了java的開發風格已經越來越接近scala這門語言,那麼scala編程語言究竟有怎樣的魅力?通過scala語言官網我們可以知道這是一門與java相同運行在jvm上的高級語言。
官方介紹:
Scala combines object-oriented and functional programming in one
concise, high-level language. Scala’s static types help avoid bugs in
complex applications, and its JVM and JavaScript runtimes let you
build high-performance systems with easy access to huge ecosystems of
libraries.
通過這個介紹我們大概就可以知道scala是一門函數式編程語言,相信接觸過java8開發的同學都知道函數式編程的巧妙之處了。scala具體有多牛逼就自行百度啦。
3 how to do 怎麼去使用它?
扯了這麼多終於奔入主題啦
首先和java相同導入maven依賴
maven依賴:(注意安裝依賴環境之前請確保已經安裝了idea plugins支持scala 的插件)
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<!--定義項目相關的版本號-->
<properties>
<java.version>1.8</java.version>
<lombok.version>1.18.6</lombok.version>
<scala.version>2.12.4</scala.version>
<scala.maven.version>3.3.1</scala.maven.version>
<scala.complie.version>0.9.0</scala.complie.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- Need this to compile JSP -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!--spring-web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- scala -->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<!--scala.complie-->
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-java8-compat_2.12</artifactId>
<version>${scala.complie.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala.maven.version}</version>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
4.編寫一個簡單的hello wolrd網頁?
application文件的配置:
server.port=8888
同java相似 我們也創建相應的controller來測試一下吧
創建IndexController.scala文件 注意是scala文件不要創建成java了
編寫代碼:(注意scala的requestMapping只接受Array())
package com.example.demo.controller
import org.springframework.web.bind.annotation.{RequestMapping, RestController}
@RestController
@RequestMapping(Array("/"))
class IndexController {
@RequestMapping(Array("/welcome"))
def welcome() = {
"hello scala!!!"
}
}
5 簡單測試一下?
測試沒問題啦。
6 如何注入service 層?
service層代碼:(需要導入springboot-web模塊)
@Service
class UserService {
def query(): Array[Int] = {
val array = Array[Int](3, 4, 5)
array
}
}
controller層代碼
@ResponseBody
@RequestMapping(Array("/userList"))
def userList() = {
val list = userService.query()
for (ele <- list) println(ele)
"userList"
}
7 什麼這些還不夠? 從項目的角度開發?
從零到一開發一個微信公衆號推送demo?
導入項目相關的maven 這裏推薦使用(com.github.binarywang)這個開源項目進行公衆號開發
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>${weixin-java-mp.version}</version>
</dependency>
<!--fashjson工具類-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
實體類:
AccessToken
package com.example.demo.pojo
case class AccessToken(access_token:String,expires_in:String){
}
service 類:
package com.example.demo.service
import java.io.IOException
import java.net.{MalformedURLException, URL, URLConnection}
import java.security.{MessageDigest, NoSuchAlgorithmException}
import java.util.Optional
import com.alibaba.fastjson.JSON
import com.example.demo.CommonUtils
import com.example.demo.pojo.AccessToken
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.{Component, Service}
@Slf4j
@Service
@Component
class WxServiceScala {
var GET_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"
var TOKEN: String = _
var APPID: String = _
var APPSECRET: String = _
var APPKEY: String = _
var ac: AccessToken = _
/**
* 未來的過期時間
*/
var futureExpireTime: Optional[Long] = _;
@Value(value = "${wx.token}") def setTOKEN(token: String): Unit = {
TOKEN = token
}
@Value(value = "${wx.appId}") def setAPPID(appId: String): Unit = {
APPID = appId
}
@Value(value = "${wx.appSecret}") def setAPPSECRET(appsecret: String): Unit = {
APPSECRET = appsecret
}
def checkSign(timestamp: String, nonce: String, echostr: String, signature: String): Boolean = {
val array = Array[String](TOKEN, timestamp, nonce)
val str = new StringBuilder
for (elem <- array.sorted) {
elem -> {}
str.append(elem);
}
sha1(str.toString()).eq(signature);
}
/**
* 獲取token值
*/
def getToken(): Unit = {
println("===APPID===" + APPID + "======APPSECRET===" + APPSECRET + "========")
val url = GET_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET)
val str = get(url)
println("str" + str)
val accessToken = JSON.parseObject(str, classOf[AccessToken])
futureExpireTime = Optional.of(System.currentTimeMillis + accessToken.expires_in.toInt * 1000)
ac = accessToken
println(ac.toString)
println("======futureExpireTime=====未來過期時間==" + futureExpireTime)
}
/**
* 判斷當前時間過期了嗎
*
* @return
*/
def isExpired: Boolean = System.currentTimeMillis > futureExpireTime.orElse(0L)
/**
* 獲取token值 有效期目前爲2個小時
*
* @return
*/
def getAccessToken: String = {
if (ac == null || isExpired) getToken()
ac.access_token
}
def sha1(src: String): String = {
try {
val md = MessageDigest.getInstance("sha1")
val digest = md.digest(src.getBytes)
val chars = Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
val sb = new StringBuilder
for (b <- digest) {
sb.append(chars((b >> 4) & 15))
sb.append(chars(b & 15))
}
return sb.toString
} catch {
case e: NoSuchAlgorithmException =>
e.printStackTrace()
}
null
}
/**
* @param url
* @return
*/
def get(url: String): String = {
try {
val urlObj = new URL(url)
val connection = urlObj.openConnection
val is = connection.getInputStream
val b = new Array[Byte](1024)
var len = 0
val sb = new StringBuilder
while ( {
(len = is.read(b)) != -1
}) sb.append(new String(b, 0, len))
return sb.toString
} catch {
case e: MalformedURLException =>
e.printStackTrace()
case e: IOException =>
e.printStackTrace()
}
null
}
}
用於認證測試的controller類
package com.example.demo.controller
import com.example.demo.service.WxServiceScala
import javax.servlet.http.HttpServletRequest
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.{GetMapping, PostMapping, RequestMapping, RestController}
@RestController
@RequestMapping(Array("/wechat/scala"))
class WeChatAuthController @Autowired()(wxService: WxServiceScala) {
@GetMapping(Array(""))
def auth(signature: String, timestamp: String, nonce: String, echostr: String): String = {
println("======signature=======" + signature)
println("======timestamp=======" + timestamp)
println("======nonce=======" + nonce)
println("======echostr=======" + echostr)
if (wxService.checkSign(timestamp, nonce, echostr, signature)) {
return echostr
}
"error"
}
@PostMapping(Array(""))
def getMessage(req: HttpServletRequest): Unit ={
req.setCharacterEncoding("UTF-8")
println("response post")
}
}
yml文件 填上自己的微信公衆號配置
server:
port: 8888
wx.token:
wx.appId:
wx.appSecret:
如何調用模版接口?(以java爲案例,後續會附上scala版的)
注意:微信公衆號測試模版接口需要在測試頁面申請模版Id
WxMpDefaultConfigImpl wxStorage = new WxMpDefaultConfigImpl();
wxStorage.setAccessToken(wxService.getAccessToken());
wxStorage.setAppId(WxService.APPID);
wxStorage.setAesKey(WxService.APPKEY);
wxStorage.setSecret(WxService.APPSECRET);
WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(wxStorage);
WxMpTemplateMessage templateMessage = WxMpTemplateMessage
.builder()
// 接收者openid
.toUser(wechatId)
// 模板id
.templateId(Constants.WECHAT_TEMPLATE_ID)
.miniProgram(new WxMpTemplateMessage.MiniProgram())
// 模板跳轉鏈接 跳轉到微信小程序
.build();
// 添加模板數據
templateMessage.addData(new WxMpTemplateData("first", "", "#000000"))
.addData(new WxMpTemplateData("keyword1", “”, "#000000"))
.addData(new WxMpTemplateData("keyword2", “").format(new Date()), "#000000"))
.addData(new WxMpTemplateData("remark", “”, "#ff0000"));
String result = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
代碼在哪?(地址附上):https://github.com/RAOE/scalaDemo.git
由於本文作者水平有限,筆誤之處歡迎指正。謝謝