-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.json
1 lines (1 loc) · 258 KB
/
content.json
1
{"meta":{"title":"一起学编程","subtitle":"Java,Python,Koxlin...","description":"整合各种编程语言","author":"edurtio","url":"https://learn-programming.edurt.io"},"pages":[{"title":"关于我们","date":"2020-05-08T02:40:39.788Z","updated":"2020-05-08T02:40:39.788Z","comments":true,"path":"about/index.html","permalink":"https://learn-programming.edurt.io/about/index.html","excerpt":"","text":"关于我们!!!"},{"title":"分类","date":"2020-05-08T02:40:39.788Z","updated":"2020-05-08T02:40:39.788Z","comments":true,"path":"categories/index.html","permalink":"https://learn-programming.edurt.io/categories/index.html","excerpt":"","text":""},{"title":"标签","date":"2020-05-08T02:40:39.789Z","updated":"2020-05-08T02:40:39.789Z","comments":true,"path":"tags/index.html","permalink":"https://learn-programming.edurt.io/tags/index.html","excerpt":"","text":""}],"posts":[{"title":"开发存储服务器教程","slug":"Java/SpringBoot/storage","date":"2020-10-10T09:41:40.000Z","updated":"2020-10-10T09:41:57.085Z","comments":true,"path":"2020/10/10/Java/SpringBoot/storage.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/10/Java/SpringBoot/storage.html","excerpt":"","text":"今天我们尝试使用Spring Boot开发一个数据存储服务. 基础环境 技术 版本 Java 1.8+ SpringBoot 1.5.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.sliss -DartifactId=spring-learn-integration-springboot-storage -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加java和springboot的支持 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-springboot</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-springboot-storage</artifactId> <name>SpringBoot开发存储服务器</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootStorageIntegration </p> * <p> Description : SpringBootStorageIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-10 15:53 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootStorageIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootStorageIntegration.class, args); }} 添加Rest API接口功能(提供上传服务) 创建一个controller文件夹并在该文件夹下创建UploadController Rest API接口,我们提供一个简单的文件上传接口 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.controller;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;/** * <p> UploadController </p> * <p> Description : UploadController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-10 15:55 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"upload\")public class UploadController { // 文件上传地址 private final static String UPLOADED_FOLDER = \"/Users/shicheng/Desktop/test/\"; @PostMapping public String upload(@RequestParam(\"file\") MultipartFile file) { if (file.isEmpty()) { return \"上传文件不能为空\"; } try { byte[] bytes = file.getBytes(); Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename()); Files.write(path, bytes); return \"上传文件成功\"; } catch (IOException ioe) { return \"上传文件失败,失败原因: \" + ioe.getMessage(); } } @GetMapping public Object get() { File file = new File(UPLOADED_FOLDER); String[] filelist = file.list(); return filelist; } @DeleteMapping public String delete(@RequestParam(value = \"file\") String file) { File source = new File(UPLOADED_FOLDER + file); source.delete(); return \"删除文件\" + file + \"成功\"; }} 修改SpringBootAngularIntegration类文件增加以下设置扫描路径,以便扫描Controller 123456789101112131415161718192021222324252627282930313233343536373839404142/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ComponentScan;/** * <p> SpringBootStorageIntegration </p> * <p> Description : SpringBootStorageIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-10 15:53 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplication@ComponentScan(value = { \"com.edurt.sli.sliss.controller\"})public class SpringBootStorageIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootStorageIntegration.class, args); }} 启动服务,测试API接口可用性 在编译器中直接启动SpringBootStorageIntegration类文件即可,或者打包jar启动,打包命令mvn clean package 测试上传文件接口 1curl localhost:8080/upload -F \"file=@/Users/shicheng/Downloads/qrcode/qrcode_for_ambari.jpg\" 返回结果 1上传文件成功 测试查询文件接口 1curl localhost:8080/upload 返回结果 1[\"qrcode_for_ambari.jpg\"] 测试删除接口 1curl -X DELETE 'localhost:8080/upload?file=qrcode_for_ambari.jpg' 返回结果 1删除文件qrcode_for_ambari.jpg成功 再次查询查看文件是否被删除 1curl localhost:8080/upload 返回结果 1[] 增加下载文件支持 在controller文件夹下创建DownloadController Rest API接口,我们提供一个文件下载接口 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;import java.io.*;/** * <p> DownloadController </p> * <p> Description : DownloadController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-10 16:21 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"download\")public class DownloadController { private final static String UPLOADED_FOLDER = \"/Users/shicheng/Desktop/test/\"; @GetMapping public String download(@RequestParam(value = \"file\") String file, HttpServletResponse response) { if (!file.isEmpty()) { File source = new File(UPLOADED_FOLDER + file); if (source.exists()) { response.setContentType(\"application/force-download\");// 设置强制下载不打开 response.addHeader(\"Content-Disposition\", \"attachment;fileName=\" + file);// 设置文件名 byte[] buffer = new byte[1024]; FileInputStream fileInputStream = null; BufferedInputStream bufferedInputStream = null; try { fileInputStream = new FileInputStream(source); bufferedInputStream = new BufferedInputStream(fileInputStream); OutputStream outputStream = response.getOutputStream(); int i = bufferedInputStream.read(buffer); while (i != -1) { outputStream.write(buffer, 0, i); i = bufferedInputStream.read(buffer); } return \"文件下载成功\"; } catch (Exception e) { e.printStackTrace(); } finally { if (bufferedInputStream != null) { try { bufferedInputStream.close(); } catch (IOException e) { return \"文件下载失败,失败原因: \" + e.getMessage(); } } if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { return \"文件下载失败,失败原因: \" + e.getMessage(); } } } } } return \"文件下载失败\"; }} 测试下载文件 1curl -o a.jpg 'localhost:8080/download?file=qrcode_for_ambari.jpg' 出现以下进度条 123 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 148k 0 148k 0 0 11.3M 0 --:--:-- --:--:-- --:--:-- 12.0M 查询是否下载到本地文件夹 1ls a.jpg 返回结果 1a.jpg 文件大小设置 默认情况下,Spring Boot最大文件上传大小为1MB,您可以通过以下应用程序属性配置值: 配置文件 1234#http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties#search multipartspring.http.multipart.max-file-size=10MBspring.http.multipart.max-request-size=10MB 代码配置,创建一个config文件夹,并在该文件夹下创建MultipartConfig 123456789101112131415161718192021222324252627282930313233343536373839404142434445/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.config;import org.springframework.boot.web.servlet.MultipartConfigFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.servlet.MultipartConfigElement;/** * <p> MultipartConfig </p> * <p> Description : MultipartConfig </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-10 16:34 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Configurationpublic class MultipartConfig { @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize(\"10240KB\"); //KB,MB factory.setMaxRequestSize(\"102400KB\"); return factory.createMultipartConfig(); }} 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-springboot-storage-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"SpringBoot","slug":"Java/SpringBoot","permalink":"https://learn-programming.edurt.io/categories/Java/SpringBoot/"}],"tags":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/tags/Java/"},{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://learn-programming.edurt.io/tags/SpringBoot/"}]},{"title":"整合Scala教程","slug":"Java/SpringBoot/scala","date":"2020-10-10T09:40:38.000Z","updated":"2020-10-10T09:41:10.367Z","comments":true,"path":"2020/10/10/Java/SpringBoot/scala.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/10/Java/SpringBoot/scala.html","excerpt":"","text":"今天我们尝试Spring Boot整合Scala,并决定建立一个非常简单的Spring Boot微服务,使用Scala作为编程语言进行编码构建。 基础环境 技术 版本 Java 1.8+ SpringBoot 2.1.x Scala 2.12.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.sliss -DartifactId=springboot-scala-integration -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加java和scala的支持 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-springboot</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-springboot-scala</artifactId> <name>SpringBoot整合Scala</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <!-- dependency config --> <dependency.scala.version>2.12.1</dependency.scala.version> <!-- plugin config --> <plugin.maven.scala.version>3.1.3</plugin.maven.scala.version> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${dependency.scala.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <sourceDirectory>${project.basedir}/src/main/scala</sourceDirectory> <testSourceDirectory>${project.basedir}/src/test/scala</testSourceDirectory> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>${plugin.maven.scala.version}</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.3.RELEASE</version> </plugin> </plugins> </build></project> 一个简单的应用类 123456789101112131415161718192021222324252627282930/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slissimport org.springframework.boot.SpringApplicationimport org.springframework.boot.autoconfigure.SpringBootApplication@SpringBootApplicationclass SpringBootScalaIntegrationobject SpringBootScalaIntegration extends App{ SpringApplication.run(classOf[SpringBootScalaIntegration])} 添加Rest API接口功能 创建一个HelloController Rest API接口,我们只提供一个简单的get请求获取hello,scala输出信息 123456789101112131415161718192021222324252627282930/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.controllerimport org.springframework.web.bind.annotation.{GetMapping, RestController}@RestControllerclass HelloController { @GetMapping(value = Array(\"hello\")) def hello(): String = { return \"hello,scala\" }} 修改SpringBootScalaIntegration文件增加以下设置扫描路径 12345678910111213141516171819202122232425262728293031323334/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slissimport org.springframework.boot.SpringApplicationimport org.springframework.boot.autoconfigure.SpringBootApplicationimport org.springframework.context.annotation.ComponentScan@SpringBootApplication@ComponentScan(value = Array( \"com.edurt.sli.sliss.controller\"))class SpringBootScalaIntegrationobject SpringBootScalaIntegration extends App { SpringApplication.run(classOf[SpringBootScalaIntegration])} 添加页面功能 修改pom.xml文件增加以下页面依赖 123456<!-- mustache --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mustache</artifactId> <version>2.1.3.RELEASE</version></dependency> 修改SpringBootScalaIntegration文件增加以下设置扫描路径ComponentScan的value字段中 1234567891011121314151617181920212223242526272829303132333435/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slissimport org.springframework.boot.SpringApplicationimport org.springframework.boot.autoconfigure.SpringBootApplicationimport org.springframework.context.annotation.ComponentScan@SpringBootApplication@ComponentScan(value = Array( \"com.edurt.sli.sliss.controller\", \"com.edurt.sli.sliss.view\" // 增加扫描路径))class SpringBootScalaIntegrationobject SpringBootScalaIntegration extends App { SpringApplication.run(classOf[SpringBootScalaIntegration])} 在src/main/resources路径下创建templates文件夹 在templates文件夹下创建一个名为hello.mustache的页面文件 1<h1>Hello, Scala</h1> 创建view文件夹,并在该文件夹下创建页面转换器HelloView 12345678910111213141516171819202122232425262728293031/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.viewimport org.springframework.stereotype.Controllerimport org.springframework.web.bind.annotation.GetMapping@Controllerclass HelloView { @GetMapping(value = Array(\"hello_view\")) def helloView: String = { return \"hello\"; }} 浏览器访问http://localhost:8080/hello_view即可看到页面内容 添加数据持久化功能 修改pom.xml文件增加以下依赖(由于测试功能我们使用h2内存数据库) 123456789101112<!-- data jpa and db --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>2.1.3.RELEASE</version></dependency><dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.1.3.RELEASE</version> <scope>runtime</scope></dependency> 修改SpringBootScalaIntegration文件增加以下设置扫描model路径 1\"com.edurt.sli.sliss.model\" 创建model文件夹,并在该文件夹下创建User实体 12345678910111213141516171819202122232425262728293031/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.modelimport javax.persistence.{Entity, GeneratedValue, Id}@Entityclass UserModel { @Id @GeneratedValue var id: Long = 0 var name: String = null} 创建UserSupport dao数据库操作工具类 12345678910111213141516171819202122232425/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.supportimport com.edurt.sli.sliss.model.UserModelimport org.springframework.data.repository.PagingAndSortingRepositorytrait UserSupport extends PagingAndSortingRepository[UserModel, Long] {} 创建UserService服务类 1234567891011121314151617181920212223242526272829/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.serviceimport com.edurt.sli.sliss.model.UserModeltrait UserService { /** * save model to db */ def save(model: UserModel): UserModel;} 创建UserServiceImpl实现类 12345678910111213141516171819202122232425262728293031323334353637/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.serviceimport com.edurt.sli.sliss.model.UserModelimport com.edurt.sli.sliss.support.UserSupportimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.stereotype.Service@Service(value = \"userService\")class UserServiceImpl @Autowired() ( val userSupport: UserSupport ) extends UserService { /** * save model to db */ override def save(model: UserModel): UserModel = { return this.userSupport.save(model) }} 创建用户UserController进行持久化数据 12345678910111213141516171819202122232425262728293031323334353637383940/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.controllerimport com.edurt.sli.sliss.model.UserModelimport com.edurt.sli.sliss.service.UserServiceimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.web.bind.annotation.{PathVariable, PostMapping, RequestMapping, RestController}@RestController@RequestMapping(value = Array(\"user\"))class UserController @Autowired()( val userService: UserService ) { @PostMapping(value = Array(\"save/{name}\")) def save(@PathVariable name: String): Long = { val userModel = { new UserModel() } userModel.name = name return this.userService.save(userModel).id }} 使用控制台窗口执行以下命令保存数据 1curl -X POST http://localhost:8080/user/save/qianmoQ 收到返回结果 11 表示数据保存成功 增加数据读取渲染功能 修改UserService增加以下代码 1234567891011121314151617181920212223242526272829303132333435/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.serviceimport com.edurt.sli.sliss.model.UserModelimport org.springframework.data.domain.{Page, Pageable}trait UserService { /** * save model to db */ def save(model: UserModel): UserModel; /** * get all model */ def getAll(page: Pageable): Page[UserModel]} 修改UserServiceImpl增加以下代码 123456789101112131415161718192021222324252627282930313233343536373839404142434445/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.serviceimport com.edurt.sli.sliss.model.UserModelimport com.edurt.sli.sliss.support.UserSupportimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.stereotype.Serviceimport org.springframework.data.domain.{Page, Pageable}@Service(value = \"userService\")class UserServiceImpl @Autowired() ( val userSupport: UserSupport ) extends UserService { /** * save model to db */ override def save(model: UserModel): UserModel = { return this.userSupport.save(model) } /** * get all model */ override def getAll(page: Pageable): Page[UserModel] = { return this.userSupport.findAll(page) }} 修改UserController增加以下代码 1234567891011121314151617181920212223242526272829303132333435363738394041424344/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.controllerimport com.edurt.sli.sliss.model.UserModelimport com.edurt.sli.sliss.service.UserServiceimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.data.domain.{Page, PageRequest}import org.springframework.web.bind.annotation._@RestController@RequestMapping(value = Array(\"user\"))class UserController @Autowired()( val userService: UserService ) { @PostMapping(value = Array(\"save/{name}\")) def save(@PathVariable name: String): Long = { val userModel = { new UserModel() } userModel.name = name return this.userService.save(userModel).id } @GetMapping(value = Array(\"list\")) def get(): Page[UserModel] = this.userService.getAll(PageRequest.of(0, 10))} 创建UserView文件渲染User数据 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.sliss.viewimport com.edurt.sli.sliss.service.UserServiceimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.data.domain.PageRequestimport org.springframework.stereotype.Controllerimport org.springframework.ui.Modelimport org.springframework.web.bind.annotation.GetMapping@Controllerclass UserView @Autowired()( private val userService: UserService ) { @GetMapping(value = Array(\"user_view\")) def helloView(model: Model): String = { model.addAttribute(\"users\", this.userService.getAll(PageRequest.of(0, 10))) return \"user\" }} 创建user.mustache文件渲染数据(自行解析返回数据即可) 1{{users}} 浏览器访问http://localhost:8080/user_view即可看到页面内容 增加单元功能 修改pom.xml文件增加以下依赖 1234567891011121314151617181920212223<!-- test --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>2.1.3.RELEASE</version> <scope>test</scope> <exclusions> <exclusion> <groupId>junit</groupId> <artifactId>junit</artifactId> </exclusion> <exclusion> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> </exclusion> </exclusions></dependency><dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.3.2</version> <scope>test</scope></dependency> 创建UserServiceTest文件进行测试UserService功能 12345678910111213141516171819202122232425262728293031323334353637/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slissimport com.edurt.sli.sliss.service.UserServiceimport org.junit.jupiter.api.Testimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.boot.test.context.SpringBootTestimport org.springframework.data.domain.PageRequest@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)class UserServiceTest @Autowired()( private val userService: UserService) { @Test def `get all`() { println(\">> Assert blog page title, content and status code\") val entity = this.userService.getAll(PageRequest.of(0, 1)) print(entity.getTotalPages) }} 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-springboot-scala-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"SpringBoot","slug":"Java/SpringBoot","permalink":"https://learn-programming.edurt.io/categories/Java/SpringBoot/"}],"tags":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/tags/Java/"},{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://learn-programming.edurt.io/tags/SpringBoot/"},{"name":"Scala","slug":"Scala","permalink":"https://learn-programming.edurt.io/tags/Scala/"}]},{"title":"整合Angular前后端开发教程","slug":"Java/SpringBoot/angular","date":"2020-10-10T09:38:57.000Z","updated":"2020-10-10T09:39:30.598Z","comments":true,"path":"2020/10/10/Java/SpringBoot/angular.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/10/Java/SpringBoot/angular.html","excerpt":"","text":"今天我们尝试Spring Boot整合Angular,并决定建立一个非常简单的Spring Boot微服务,使用Angular作为前端渲编程语言进行前端页面渲染. 基础环境 技术 版本 Java 1.8+ SpringBoot 1.5.x Angular 7.x.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slisa -DartifactId=spring-learn-integration-springboot-angular -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加java和springboot的支持 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-springboot</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-springboot-angular</artifactId> <name>SpringBoot整合Angular前后端开发</name> <properties> <!-- 系统 --> <system.java.version>1.8</system.java.version> <!-- 依赖 --> <dependency.springboot.version>1.5.6.RELEASE</dependency.springboot.version> <!-- 插件 --> <plugin.maven.compiler.version>3.1</plugin.maven.compiler.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisa;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootAngularIntegration </p> * <p> Description : SpringBootAngularIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-03 18:26 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootAngularIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootAngularIntegration.class, args); }} 添加Rest API接口功能 创建一个model文件夹并在该文件夹下创建Model类,用于存放数据模型 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisa.model;/** * <p> Model </p> * <p> Description : Model </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-05 20:00 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */public class Model { private String key; private String value; public Model() { } public Model(String key, String value) { this.key = key; this.value = value; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; }} 创建一个controller文件夹并在该文件夹下创建HelloAngularController Rest API接口,我们只提供一个简单的添加,删除,修改,查询列表的接口 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisa.controller;import com.edurt.sli.slisa.model.Model;import org.springframework.web.bind.annotation.*;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/** * <p> HelloAngularController </p> * <p> Description : HelloAngularController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-05 19:36 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@CrossOriginpublic class HelloAngularController { private final static Map<String, Object> DATA_STORAGE = new ConcurrentHashMap<String, Object>(); public HelloAngularController() { DATA_STORAGE.put(\"1\", \"Hello Java\"); } /** * 查询所有数据信息 * * @return 所有数据信息 */ @GetMapping(value = \"get\") public Map getAll() { return DATA_STORAGE; } /** * 新建数据 * * @param model 数据模型 * @return 创建结果 */ @PostMapping(value = \"post\") public String post(@RequestBody Model model) { DATA_STORAGE.put(model.getKey(), model.getValue()); return \"SUCCESS\"; } /** * 更新数据 * * @param model 数据模型 * @return 更新结果 */ @PutMapping(value = \"put\") public String put(@RequestBody Model model) { if (DATA_STORAGE.containsKey(model.getKey())) { DATA_STORAGE.put(model.getKey(), model.getValue()); } return \"SUCCESS\"; } /** * 删除数据 * * @param key 数据标志 * @return 删除结果 */ @DeleteMapping(value = \"delete\") public String delete(@RequestParam String key) { if (DATA_STORAGE.containsKey(key)) { DATA_STORAGE.remove(key); } return \"SUCCESS\"; }} 修改SpringBootAngularIntegration类文件增加以下设置扫描路径,以便扫描Controller 123456789101112131415161718192021222324252627282930313233343536373839404142/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisa;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ComponentScan;/** * <p> SpringBootAngularIntegration </p> * <p> Description : SpringBootAngularIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-03 18:26 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplication@ComponentScan(value = { \"com.edurt.sli.slisa.controller\"})public class SpringBootAngularIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootAngularIntegration.class, args); }} 启动服务,测试API接口可用性 在编译器中直接启动SpringBootAngularIntegration类文件即可,或者打包jar启动,打包命令mvn clean package 测试查询数据接口 1curl -X GET http://localhost:8080/get 返回结果 1{\"1\":\"Hello Java\"} 测试新增数据接口 1curl -X POST http://localhost:8080/post -H 'Content-Type:application/json' -d '{\"key\": \"2\", \"value\": \"Hello Angular\"}' 返回结果 1SUCCESS 再次查询查看数据是否添加 1curl -X GET http://localhost:8080/get 返回结果 1{\"1\":\"Hello Java\",\"2\":\"Hello Angular\"} 测试修改数据接口 1curl -X PUT http://localhost:8080/put -H 'Content-Type:application/json' -d '{\"key\": \"1\", \"value\": \"Hello Angular\"}' 返回结果 1SUCCESS 再次查询查看数据是否修改 1curl -X GET http://localhost:8080/get 返回结果 1{\"1\":\"Hello Angular\",\"2\":\"Hello Angular\"} 测试删除数据接口 1curl -X DELETE 'http://localhost:8080/delete?key=1' 返回结果 1SUCCESS 再次查询查看数据是否删除 1curl -X GET http://localhost:8080/get 返回结果 1{\"2\":\"Hello Angular\"} 增加Angular支持 我们使用ng脚手架进行初始化一个新的angular项目.不过需要我们先安装脚手架 1npm install -g @angular/cli 生成Angular项目 1ng new angular 生成项目的时候会自动安装相关依赖可能会慢,请耐心等待,中间出现的任何输入形式我们只需要回车即可. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263? Would you like to add Angular routing? Yes? Which stylesheet format would you like to use? SCSS [ http://sass-lang.com ]CREATE angular/README.md (1024 bytes)CREATE angular/angular.json (3868 bytes)CREATE angular/package.json (1306 bytes)CREATE angular/tsconfig.json (435 bytes)CREATE angular/tslint.json (2824 bytes)CREATE angular/.editorconfig (246 bytes)CREATE angular/.gitignore (576 bytes)CREATE angular/src/favicon.ico (5430 bytes)CREATE angular/src/index.html (294 bytes)CREATE angular/src/main.ts (372 bytes)CREATE angular/src/polyfills.ts (3234 bytes)CREATE angular/src/test.ts (642 bytes)CREATE angular/src/styles.scss (80 bytes)CREATE angular/src/browserslist (388 bytes)CREATE angular/src/karma.conf.js (980 bytes)CREATE angular/src/tsconfig.app.json (166 bytes)CREATE angular/src/tsconfig.spec.json (256 bytes)CREATE angular/src/tslint.json (314 bytes)CREATE angular/src/assets/.gitkeep (0 bytes)CREATE angular/src/environments/environment.prod.ts (51 bytes)CREATE angular/src/environments/environment.ts (662 bytes)CREATE angular/src/app/app-routing.module.ts (245 bytes)CREATE angular/src/app/app.module.ts (393 bytes)CREATE angular/src/app/app.component.scss (0 bytes)CREATE angular/src/app/app.component.html (1152 bytes)CREATE angular/src/app/app.component.spec.ts (1098 bytes)CREATE angular/src/app/app.component.ts (212 bytes)CREATE angular/e2e/protractor.conf.js (752 bytes)CREATE angular/e2e/tsconfig.e2e.json (213 bytes)CREATE angular/e2e/src/app.e2e-spec.ts (299 bytes)CREATE angular/e2e/src/app.po.ts (204 bytes)npm WARN deprecated [email protected]: This module is no longer maintained, try this instead:npm WARN deprecated npm i nycnpm WARN deprecated Visit https://istanbul.js.org/integrations for other alternatives.npm WARN deprecated [email protected]: CircularJSON is in maintenance only, flatted is its successor.> [email protected] install /Users/shicheng/angular/node_modules/fsevents> node installnode-pre-gyp WARN Using request for node-pre-gyp https download[fsevents] Success: "/Users/shicheng/angular/node_modules/fsevents/lib/binding/Release/node-v57-darwin-x64/fse.node" is installed via remote> [email protected] install /Users/shicheng/angular/node_modules/node-sass> node scripts/install.jsCached binary found at /Users/shicheng/.npm/node-sass/4.10.0/darwin-x64-57_binding.node> [email protected] postinstall /Users/shicheng/angular/node_modules/core-js> node scripts/postinstall || echo "ignore"> [email protected] postinstall /Users/shicheng/angular/node_modules/node-sass> node scripts/build.jsBinary found at /Users/shicheng/angular/node_modules/node-sass/vendor/darwin-x64-57/binding.nodeTesting binaryBinary is finenpm WARN [email protected] requires a peer of ajv@^6.9.1 but none is installed. You must install peer dependencies yourself.added 1221 packages in 64.411s Successfully initialized git. 创建angula源码目录 在src/main/下新建angulars目录,并将刚刚生成的代码文件全部复制到该文件夹下(注意隐藏文件也需要复制) 修改app.module.ts引入HttpClient模块增加访问后端服务支持 1234567891011121314151617181920212223import {BrowserModule} from '@angular/platform-browser';import {NgModule} from '@angular/core';import {AppRoutingModule} from './app-routing.module';import {AppComponent} from './app.component';import {HttpClientModule} from \"@angular/common/http\";import {FormsModule} from \"@angular/forms\";@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, HttpClientModule, FormsModule ], providers: [], bootstrap: [AppComponent]})export class AppModule {} 修改app.component.ts访问后端数据 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253import {Component} from '@angular/core';import {HttpClient, HttpHeaders} from \"@angular/common/http\";@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss']})export class AppComponent { title = 'angular'; public list; public data = { key: '', value: '' } constructor(private http: HttpClient) { this.init(); } init() { this.http.get('/get').subscribe((res) => { this.list = res; console.log(res) } ); } add() { const headers = new HttpHeaders().set( \"Content-type\", \"application/json; charset=UTF-8\" ); this.http.post('/post', this.data, {headers}).subscribe(); this.init(); } delete() { this.http.delete('/delete?key=' + this.data.key).subscribe(); this.init(); } modfiy() { const headers = new HttpHeaders().set( \"Content-type\", \"application/json; charset=UTF-8\" ); this.http.post('/post', this.data, {headers}).subscribe(); this.init(); }} 修改app.component.html渲染后端数据 123456789101112131415161718192021222324252627282930<!--The content below is only a placeholder and can be replaced.--><div style=\"text-align:center\"> <h1> Welcome to {{ title }}! </h1> <img width=\"300\" alt=\"Angular Logo\" src=\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==\"></div><h2>Here are some links to help you start: </h2><ul> {{list | json}}</ul><form> <input [(ngModel)]=\"data.key\" name=\"name\" #name=\"ngModel\"/> <input [(ngModel)]=\"data.value\" name=\"value\" #value=\"ngModel\"/> <button (click)=\"add()\">添加</button></form><form> <input [(ngModel)]=\"data.key\" name=\"name\" #name=\"ngModel\"/> <button (click)=\"delete()\">删除</button></form><form> <input [(ngModel)]=\"data.key\" name=\"name\" #name=\"ngModel\"/> <input [(ngModel)]=\"data.value\" name=\"value\" #value=\"ngModel\"/> <button (click)=\"modfiy()\">修改</button></form><router-outlet></router-outlet> 支持打包输出 修改angulars目录下的angular.json配置文件增加输出目录以便支持打包文件到jar中(“outDir”: “../resources/static”) 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140{ \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\", \"version\": 1, \"newProjectRoot\": \"projects\", \"projects\": { \"angular\": { \"root\": \"\", \"sourceRoot\": \"src\", \"outDir\": \"../resources/static\", \"projectType\": \"application\", \"prefix\": \"app\", \"schematics\": { \"@schematics/angular:component\": { \"styleext\": \"scss\" } }, \"architect\": { \"build\": { \"builder\": \"@angular-devkit/build-angular:browser\", \"options\": { \"outputPath\": \"dist/angular\", \"index\": \"src/index.html\", \"main\": \"src/main.ts\", \"polyfills\": \"src/polyfills.ts\", \"tsConfig\": \"src/tsconfig.app.json\", \"assets\": [ \"src/favicon.ico\", \"src/assets\" ], \"styles\": [ \"src/styles.scss\" ], \"scripts\": [] }, \"configurations\": { \"production\": { \"fileReplacements\": [ { \"replace\": \"src/environments/environment.ts\", \"with\": \"src/environments/environment.prod.ts\" } ], \"optimization\": true, \"outputHashing\": \"all\", \"sourceMap\": false, \"extractCss\": true, \"namedChunks\": false, \"aot\": true, \"extractLicenses\": true, \"vendorChunk\": false, \"buildOptimizer\": true, \"budgets\": [ { \"type\": \"initial\", \"maximumWarning\": \"2mb\", \"maximumError\": \"5mb\" } ] } } }, \"serve\": { \"builder\": \"@angular-devkit/build-angular:dev-server\", \"options\": { \"browserTarget\": \"angular:build\" }, \"configurations\": { \"production\": { \"browserTarget\": \"angular:build:production\" } } }, \"extract-i18n\": { \"builder\": \"@angular-devkit/build-angular:extract-i18n\", \"options\": { \"browserTarget\": \"angular:build\" } }, \"test\": { \"builder\": \"@angular-devkit/build-angular:karma\", \"options\": { \"main\": \"src/test.ts\", \"polyfills\": \"src/polyfills.ts\", \"tsConfig\": \"src/tsconfig.spec.json\", \"karmaConfig\": \"src/karma.conf.js\", \"styles\": [ \"src/styles.scss\" ], \"scripts\": [], \"assets\": [ \"src/favicon.ico\", \"src/assets\" ] } }, \"lint\": { \"builder\": \"@angular-devkit/build-angular:tslint\", \"options\": { \"tsConfig\": [ \"src/tsconfig.app.json\", \"src/tsconfig.spec.json\" ], \"exclude\": [ \"**/node_modules/**\" ] } } } }, \"angular-e2e\": { \"root\": \"e2e/\", \"projectType\": \"application\", \"prefix\": \"\", \"architect\": { \"e2e\": { \"builder\": \"@angular-devkit/build-angular:protractor\", \"options\": { \"protractorConfig\": \"e2e/protractor.conf.js\", \"devServerTarget\": \"angular:serve\" }, \"configurations\": { \"production\": { \"devServerTarget\": \"angular:serve:production\" } } }, \"lint\": { \"builder\": \"@angular-devkit/build-angular:tslint\", \"options\": { \"tsConfig\": \"e2e/tsconfig.e2e.json\", \"exclude\": [ \"**/node_modules/**\" ] } } } } }, \"defaultProject\": \"angular\"} 修改maven配置增加打包依赖 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-springboot</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-springboot-angular</artifactId> <name>SpringBoot整合Angular前后端开发</name> <properties> <!-- 系统 --> <system.java.version>1.8</system.java.version> <system.node.version>v8.2.1</system.node.version> <system.npm.version>5.4.2</system.npm.version> <!-- 依赖 --> <dependency.springboot.version>1.5.6.RELEASE</dependency.springboot.version> <!-- 插件 --> <plugin.maven.compiler.version>3.1</plugin.maven.compiler.version> <plugin.frontend.version>0.0.27</plugin.frontend.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>${plugin.frontend.version}</version> <configuration> <!-- angular 源码根目录 angular --> <workingDirectory>src/main/angulars</workingDirectory> <nodeDownloadRoot>https://npm.taobao.org/mirrors/node/</nodeDownloadRoot> <!--<npmDownloadRoot>https://npm.taobao.org/mirrors/npm/</npmDownloadRoot>--> <nodeVersion>${system.node.version}</nodeVersion> <npmVersion>${system.npm.version}</npmVersion> <installDirectory>target</installDirectory> </configuration> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> <phase>generate-resources</phase> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>install</arguments> <installDirectory>target</installDirectory> </configuration> </execution> <execution> <id>angular cli build</id> <goals> <goal>npm</goal> </goals> <phase>generate-resources</phase> <configuration> <arguments>run build</arguments> </configuration> </execution> </executions> </plugin> </plugins> </build></project> 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-springboot-angular-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"SpringBoot","slug":"Java/SpringBoot","permalink":"https://learn-programming.edurt.io/categories/Java/SpringBoot/"}],"tags":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/tags/Java/"},{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://learn-programming.edurt.io/tags/SpringBoot/"},{"name":"Angular","slug":"Angular","permalink":"https://learn-programming.edurt.io/tags/Angular/"}]},{"title":"站点迁移通知","slug":"index","date":"2020-10-10T09:29:47.000Z","updated":"2020-10-10T09:35:34.276Z","comments":true,"path":"2020/10/10/index.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/10/index.html","excerpt":"","text":"https://learn-spring.incubator.edurt.io 网站已经迁移到本站点 阅读本站内容点击左侧分类菜单即可看到相应的文章信息。","categories":[],"tags":[]},{"title":"整合LDAP单点登录","slug":"Java/Security/security-ldap","date":"2020-10-09T11:49:52.000Z","updated":"2020-10-10T09:06:05.469Z","comments":true,"path":"2020/10/09/Java/Security/security-ldap.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/09/Java/Security/security-ldap.html","excerpt":"","text":"本教程主要详细讲解Spring Security使用LDAP做单点登录。 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x Security 5.x LDAP 任意版本 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slisl -DartifactId=spring-learn-integration-security-ldap -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加security的支持 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-security</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-security-ldap</artifactId> <name>SpringBoot Security使用LDAP单点登录</name> <properties> <dependency.spring.security.ldap.version>5.1.5.RELEASE</dependency.spring.security.ldap.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-ldap</artifactId> <version>${dependency.spring.security.ldap.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-boot-starter-security启动spring security安全框架spring-security-ldap启动spring security ldap框架支持 一个简单的应用类 12345678910111213141516171819202122232425262728293031323334353637383940/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisl;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.stereotype.Component;/** * <p> SpringBootSecurityLDAPIntegration </p> * <p> Description : SpringBootSecurityLDAPIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-19 19:50 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplication@Component(value = \"com.edurt.sli.slisl\")public class SpringBootSecurityLDAPIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootSecurityLDAPIntegration.class, args); }} 配置Security 在/src/main/java/com/edurt/sli/slisl目录下创建config目录,并在该目录下新建LdapConfig文件 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisl.config;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;/** * <p> LdapConfig </p> * <p> Description : LdapConfig </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-19 20:24 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Component@ConfigurationProperties(prefix = \"custom.ldap\")public class LdapConfig { private String searchBase; private String searchFilter; private String url; private String manageDN; private String managePassword; public LdapConfig() { } public String getSearchBase() { return searchBase; } public void setSearchBase(String searchBase) { this.searchBase = searchBase; } public String getSearchFilter() { return searchFilter; } public void setSearchFilter(String searchFilter) { this.searchFilter = searchFilter; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getManageDN() { return manageDN; } public void setManageDN(String manageDN) { this.manageDN = manageDN; } public String getManagePassword() { return managePassword; } public void setManagePassword(String managePassword) { this.managePassword = managePassword; }} @ConfigurationProperties(prefix = "custom.ldap")标志着配置文件中的配置是按照custom.ldap开头 创建SecurityLdapConfig授权校验文件 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisl.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/** * <p> SecurityConfig </p> * <p> Description : SecurityConfig </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-19 19:52 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Configurationpublic class SecurityLdapConfig extends WebSecurityConfigurerAdapter { @Autowired private LdapConfig config; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.ldapAuthentication() .userSearchBase(config.getSearchBase()) .userSearchFilter(config.getSearchFilter()) .contextSource() .url(config.getUrl()) .managerDn(config.getManageDN()) .managerPassword(config.getManagePassword()); }} 在resources资源目录下创建一个application.properties的配置文件,内容如下 123456server.port=8989custom.ldap.searchBase=OU=example,DC=example,DC=intracustom.ldap.searchFilter=(sAMAccountName={0})custom.ldap.url=ldap://192.168.0.5:389custom.ldap.manageDN=cn=function,OU=Email Account,dc=example,dc=intracustom.ldap.managePassword=example 创建授权成功提示 在/src/main/java/com/edurt/sli/slisl目录下创建controller目录,并在该目录下新建HelloLDAPController文件 123456789101112131415161718192021222324252627282930313233343536373839404142434445/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisl.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import java.security.Principal;import java.util.Map;/** * <p> HelloLDAPController </p> * <p> Description : HelloLDAPController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-19 20:12 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Controllerpublic class HelloLDAPController { @RequestMapping(\"/secure\") public String secure(Map<String, Object> model, Principal principal) { model.put(\"title\", \"授权成功\"); model.put(\"message\", \"仅授权可查看的页面\"); model.put(\"name\", principal.getName()); return \"home\"; }} 浏览器打开http://localhost:8989/login出现以下界面 输入你的LDAP账号信息即可校验成功,跳转到授权的数据页面 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-security-ldap-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"Security","slug":"Java/Security","permalink":"https://learn-programming.edurt.io/categories/Java/Security/"}],"tags":[{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://learn-programming.edurt.io/tags/SpringBoot/"},{"name":"LDAP","slug":"LDAP","permalink":"https://learn-programming.edurt.io/tags/LDAP/"}]},{"title":"整合KeyCloak权限管理教程","slug":"Java/Security/security-keycloak","date":"2020-10-09T11:48:31.000Z","updated":"2020-10-09T11:49:01.702Z","comments":true,"path":"2020/10/09/Java/Security/security-keycloak.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/09/Java/Security/security-keycloak.html","excerpt":"","text":"今天我们尝试Spring Boot Security整合Keycloak,并决定建立一个非常简单的Spring Boot微服务,使用Keycloak作为我的身份验证源,使用Spring Security处理身份验证和授权。 基础环境 技术 版本 Java 1.8+ SpringBoot 1.5.x KeyCloak 任意版本 设置Keycloak 首先我们需要一个Keycloak实例,让我们启动Jboss提供的Docker容器: 123456docker run -d \\ --name spring-learn-integration-springboot-security-keycloak \\ -e KEYCLOAK_USER=admin \\ -e KEYCLOAK_PASSWORD=admin \\ -p 9001:8080 \\ jboss/keycloak 在此之后,我们只需登录到容器并导航到bin文件夹。 12docker exec -it spring-learn-integration-springboot-security-keycloak /bin/bashcd keycloak/bin 首先,我们需要从CLI客户端登录keycloak服务器,之后我们不再需要身份验证: 1./kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password admin 配置realm 首先,我们需要创建一个realm: 123./kcadm.sh create realms -s realm=spring-learn-integration-springboot-security-keycloak -s enabled=trueCreated new realm with id 'spring-learn-integration-springboot-security-keycloak' 之后,我们需要创建2个客户端,这将为我们的应用程序提供身份验证。首先我们创建一个cURL客户端,这样我们就可以通过命令行命令登录: 123./kcadm.sh create clients -r spring-learn-integration-springboot-security-keycloak -s clientId=curl -s enabled=true -s publicClient=true -s baseUrl=http://localhost:8080 -s adminUrl=http://localhost:8080 -s directAccessGrantsEnabled=trueCreated new client with id '8f0481cd-3bbb-4659-850f-6088466a4d89' 重要的是要注意2个选项:publicClient=true和 directAccessGrantsEnabled=true。第一个使这个客户端公开,这意味着我们的cURL客户端可以在不提供任何秘密的情况下启动登录。第二个使我们能够使用用户名和密码直接登录。 其次,我们创建了一个由REST服务使用的客户端: 123./kcadm.sh create clients -r spring-learn-integration-springboot-security-keycloak -s clientId=spring-learn-integration-springboot-security-keycloak-client -s enabled=true -s baseUrl=http://localhost:8080 -s bearerOnly=trueCreated new client with id 'ab9d404e-6d5b-40ac-9bc3-9e2e26b68213' 这里的重要配置是bearerOnly=true。这告诉Keycloak客户端永远不会启动登录过程,但是当它收到Bearer令牌时,它将检查所述令牌的有效性。 我们应该注意保留这些ID,因为我们将在接下来的步骤中使用它们。 我们有两个客户端,接下来是为spring-security-keycloak-example-app客户创建角色 Admin Role: 123./kcadm.sh create clients/ab9d404e-6d5b-40ac-9bc3-9e2e26b68213/roles -r spring-learn-integration-springboot-security-keycloak -s name=admin -s 'description=Admin role'Created new role with id 'admin' User Role: 123./kcadm.sh create clients/ab9d404e-6d5b-40ac-9bc3-9e2e26b68213/roles -r spring-learn-integration-springboot-security-keycloak -s name=user -s 'description=User role'Created new role with id 'user' 注意client后的id是我们创建客户端输出的id 最后,我们应该获取客户端的配置,以便稍后提供给我们的应用程序: 1./kcadm.sh get clients/ab9d404e-6d5b-40ac-9bc3-9e2e26b68213/installation/providers/keycloak-oidc-keycloak-json -r spring-learn-integration-springboot-security-keycloak 注意client后的id是我们创建客户端输出的id 应该返回类似于此的内容: 12345678910{ \"realm\" : \"spring-learn-integration-springboot-security-keycloak\", \"bearer-only\" : true, \"auth-server-url\" : \"http://localhost:8080/auth\", \"ssl-required\" : \"external\", \"resource\" : \"spring-learn-integration-springboot-security-keycloak-client\", \"verify-token-audience\" : true, \"use-resource-role-mappings\" : true, \"confidential-port\" : 0} 配置用户 出于演示目的,我们创建2个具有2个不同角色的用户,以便我们验证授权是否有效。 首先,让我们创建一个具有admin角色的用户: 创建admin用户: 123./kcadm.sh create users -r spring-learn-integration-springboot-security-keycloak -s username=admin -s enabled=trueCreated new user with id '50c11a76-a8ff-42b1-80cb-d82cb3e7616d' 设置admin密码: 1./kcadm.sh update users/50c11a76-a8ff-42b1-80cb-d82cb3e7616d/reset-password -r spring-learn-integration-springboot-security-keycloak -s type=password -s value=admin -s temporary=false -n value: 用户密码 追加到admin角色中 1./kcadm.sh add-roles -r spring-learn-integration-springboot-security-keycloak --uusername=admin --cclientid spring-learn-integration-springboot-security-keycloak-client --rolename admin 注意:从不在生产中使用此方法,它仅用于演示目的! 然后我们创建另一个用户,这次有角色user: 创建user用户: 123./kcadm.sh create users -r spring-learn-integration-springboot-security-keycloak -s username=user -s enabled=trueCreated new user with id '624434c8-bce4-4b5b-b81f-e77304785803' 设置user密码: 1./kcadm.sh update users/624434c8-bce4-4b5b-b81f-e77304785803/reset-password -r spring-learn-integration-springboot-security-keycloak -s type=password -s value=admin -s temporary=false -n 追加到user角色中: 1./kcadm.sh add-roles -r spring-learn-integration-springboot-security-keycloak --uusername=user --cclientid spring-learn-integration-springboot-security-keycloak-client --rolename user Rest服务 我们已经配置了Keycloak并准备使用,我们只需要一个应用程序来使用它!所以我们创建一个简单的Spring Boot应用程序。我会在这里使用maven构建项目: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-springboot</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-springboot-security-keycloak</artifactId> <name>SpringBoot整合KeyCloak权限管理</name> <properties> <!-- dependency config --> <dependency.lombox.version>1.16.16</dependency.lombox.version> <dependency.keycloak.version>3.1.0.Final</dependency.keycloak.version> <!-- plugin config --> <plugin.maven.compiler.version>3.3</plugin.maven.compiler.version> <plugin.maven.javadoc.version>2.10.4</plugin.maven.javadoc.version> <!-- environment config --> <environment.compile.java.version>1.8</environment.compile.java.version> <!-- reporting config --> <reporting.maven.jxr.version>2.5</reporting.maven.jxr.version> </properties> <dependencies> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombox.version}</version> </dependency> <!-- springboot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- keycloak --> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> <version>${dependency.keycloak.version}</version> </dependency> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-security-adapter</artifactId> <version>${dependency.keycloak.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> 添加所有必需的依赖项: spring-security 用于保护应用程序 keycloak-spring-boot-starter 使用Keycloak和Spring Boot keycloak-spring-security-adapter与Spring Security集成 一个简单的应用类: 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slissk;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootSecurityKeyCloakIntegration </p> * <p> Description : SpringBootSecurityKeyCloakIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-02-18 14:45 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootSecurityKeyCloakIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootSecurityKeyCloakIntegration.class, args); }} Rest API接口: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slissk.controller;import org.springframework.security.access.annotation.Secured;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;/** * <p> HelloController </p> * <p> Description : HelloController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-02-18 14:50 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestControllerpublic class HelloController { @GetMapping(value = \"/admin\") @Secured(\"ROLE_ADMIN\") public String admin() { return \"Admin\"; } @GetMapping(\"/user\") @Secured(\"ROLE_USER\") public String user() { return \"User\"; }} 最后是keycloak配置: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slissk.config;import org.keycloak.adapters.KeycloakConfigResolver;import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter;import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;/** * <p> KeycloakSecurityConfigurer </p> * <p> Description : KeycloakSecurityConfigurer </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-02-18 14:51 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Configuration@EnableWebSecuritypublic class KeycloakSecurityConfigurer extends KeycloakWebSecurityConfigurerAdapter { @Bean public GrantedAuthoritiesMapper grantedAuthoritiesMapper() { SimpleAuthorityMapper mapper = new SimpleAuthorityMapper(); mapper.setConvertToUpperCase(true); return mapper; } @Override protected KeycloakAuthenticationProvider keycloakAuthenticationProvider() { final KeycloakAuthenticationProvider provider = super.keycloakAuthenticationProvider(); provider.setGrantedAuthoritiesMapper(grantedAuthoritiesMapper()); return provider; } @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(keycloakAuthenticationProvider()); } @Override protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new NullAuthenticatedSessionStrategy(); } @Override protected void configure(final HttpSecurity http) throws Exception { super.configure(http); http .authorizeRequests() .antMatchers(\"/admin\").hasRole(\"ADMIN\") .antMatchers(\"/user\").hasRole(\"USER\") .anyRequest().permitAll(); } @Bean KeycloakConfigResolver keycloakConfigResolver() { return new KeycloakSpringBootConfigResolver(); } @Bean public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean( final KeycloakAuthenticationProcessingFilter filter) { final FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter); registrationBean.setEnabled(false); return registrationBean; } @Bean public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean( final KeycloakPreAuthActionsFilter filter) { final FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter); registrationBean.setEnabled(false); return registrationBean; }} KeycloakSecurityConfigurer类扩展 KeycloakWebSecurityConfigurerAdapter,这是Keycloak提供的类,它提供与Spring Security的集成。 然后我们通过添加SimpleAuthorityMapper配置身份验证管理器,它负责转换来自Keycloak的角色名称以匹配Spring Security的约定。基本上Spring Security期望以ROLE_前缀开头的角色,ROLE_ADMIN可以像Keycloak一样命名我们的角色,或者我们可以将它们命名为admin,然后使用此映射器将其转换为大写并添加必要的ROLE_前缀: 123456789101112131415161718@Beanpublic GrantedAuthoritiesMapper grantedAuthoritiesMapper() { SimpleAuthorityMapper mapper = new SimpleAuthorityMapper(); mapper.setConvertToUpperCase(true); return mapper;}@Overrideprotected KeycloakAuthenticationProvider keycloakAuthenticationProvider() { final KeycloakAuthenticationProvider provider = super.keycloakAuthenticationProvider(); provider.setGrantedAuthoritiesMapper(grantedAuthoritiesMapper()); return provider;}@Overrideprotected void configure(final AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(keycloakAuthenticationProvider());} 我们还需要为Keycloak设置会话策略,但是当我们创建无状态REST服务时,我们并不真的想要有会话,因此我们使用NullAuthenticatedSessionStrategy: 1234@Overrideprotected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new NullAuthenticatedSessionStrategy();} 通常,Keycloak Spring Security集成从keycloak.json文件中解析keycloak配置,但是我们希望有适当的Spring Boot配置,因此我们使用Spring Boot覆盖配置解析器: 1234@BeanKeycloakConfigResolver keycloakConfigResolver() { return new KeycloakSpringBootConfigResolver();} 然后我们配置Spring Security来授权所有请求: 1234567@Overrideprotected void configure(final HttpSecurity http) throws Exception { super.configure(http); http .authorizeRequests() .anyRequest().permitAll();} 最后,根据文档,我们阻止双重注册Keycloak的过滤器: 123456789101112131415@Beanpublic FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean( final KeycloakAuthenticationProcessingFilter filter) { final FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter); registrationBean.setEnabled(false); return registrationBean;}@Beanpublic FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean( final KeycloakPreAuthActionsFilter filter) { final FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter); registrationBean.setEnabled(false); return registrationBean;} 最后,我们需要application.properties使用之前下载的值配置我们的应用程序 : 12345678server.port=9002keycloak.realm=spring-learn-integration-springboot-security-keycloakkeycloak.bearer-only=truekeycloak.auth-server-url=http://localhost:9001/authkeycloak.ssl-required=externalkeycloak.resource=spring-learn-integration-springboot-security-keycloak-clientkeycloak.use-resource-role-mappings=truekeycloak.principal-attribute=preferred_username 使用应用程序 使用curl我们创建的客户端进行身份验证,以获取访问令牌: 1export TOKEN=`curl -ss --data \"grant_type=password&client_id=curl&username=admin&password=admin\" http://localhost:9001/auth/realms/spring-learn-integration-springboot-security-keycloak/protocol/openid-connect/token | jq -r .access_token` 这将收到的访问令牌存储在TOKEN变量中。 现在我们可以检查我们的管理员是否可以访问自己的/admin接口 123curl -H \"Authorization: bearer $TOKEN\" http://localhost:9002/adminAdmin 但它无法访问/user接口: 123$ curl -H \"Authorization: bearer $TOKEN\" http://localhost:9002/user{\"timestamp\":1498728302626,\"status\":403,\"error\":\"Forbidden\",\"message\":\"Access is denied\",\"path\":\"/user\"} 对于user用户也是如此,user用户无法访问admin接口。 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-springboot-security-keycloak-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"Security","slug":"Java/Security","permalink":"https://learn-programming.edurt.io/categories/Java/Security/"}],"tags":[{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://learn-programming.edurt.io/tags/SpringBoot/"},{"name":"KeyCloak","slug":"KeyCloak","permalink":"https://learn-programming.edurt.io/tags/KeyCloak/"}]},{"title":"整合JWT授权RestAPI","slug":"Java/Security/security-jwt","date":"2020-10-09T11:46:48.000Z","updated":"2020-10-09T11:48:46.205Z","comments":true,"path":"2020/10/09/Java/Security/security-jwt.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/09/Java/Security/security-jwt.html","excerpt":"","text":"本教程主要详细讲解SpringBoot Security整合JWT授权RestAPI。 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x Security 5.x JWT 0.9.0 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slisj -DartifactId=spring-learn-integration-security-jwt -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加security和jwt的支持 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-security</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-security-jwt</artifactId> <name>SpringBoot Security整合JWT授权RestAPI</name> <properties> <system.java.version>1.8</system.java.version> <plugin.maven.compiler.version>3.3</plugin.maven.compiler.version> <dependency.springboot2.common.version>2.0.3.RELEASE</dependency.springboot2.common.version> <dependency.lombok.version>1.18.6</dependency.lombok.version> <dependency.jwt.version>0.9.0</dependency.jwt.version> <dependency.jackson.version>2.9.9</dependency.jackson.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${dependency.jwt.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${dependency.jackson.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-boot-starter-security启动spring security安全框架jjwt启动spring security jwt框架支持 一个简单的应用类 12345678910111213141516171819202122232425262728293031323334353637383940/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisj;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.stereotype.Component;/** * <p> SpringBootSecurityJwtIntegration </p> * <p> Description : SpringBootSecurityJwtIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-26 20:45 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplication@Component(value = \"com.edurt.sli.slisj\")public class SpringBootSecurityJwtIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootSecurityJwtIntegration.class, args); } } 配置 JWT 在/src/main/java/com/edurt/sli/slisj目录下创建config目录,并在该目录下新建jwt目录,在该目录下新建JwtTokenTemplate工具模板 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisj.config.jwt;import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.stereotype.Component;import java.io.Serializable;import java.time.Instant;import java.util.Date;import java.util.HashMap;import java.util.Map;/** * <p> JwtTokenTemplate </p> * <p> Description : JwtTokenTemplate </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-26 20:49 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Componentpublic class JwtTokenTemplate implements Serializable { private static final String CLAIM_KEY_USERNAME = \"sub\"; private static final long EXPIRATION_TIME = 432000000; private static final String SECRET = \"secret\"; public String generateToken(UserDetails userDetails) { Map<String, Object> claims = new HashMap<>(16); claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername()); return Jwts.builder() .setClaims(claims) .setExpiration(new Date(Instant.now().toEpochMilli() + EXPIRATION_TIME)) .signWith(SignatureAlgorithm.HS512, SECRET) .compact(); } public Boolean validateToken(String token, UserDetails userDetails) { User user = (User) userDetails; String username = getUsernameFromToken(token); return (username.equals(user.getUsername()) && !isTokenExpired(token)); } public Boolean isTokenExpired(String token) { Date expiration = getExpirationDateFromToken(token); return expiration.before(new Date()); } public String getUsernameFromToken(String token) { String username = getClaimsFromToken(token).getSubject(); return username; } public Date getExpirationDateFromToken(String token) { Date expiration = getClaimsFromToken(token).getExpiration(); return expiration; } private Claims getClaimsFromToken(String token) { Claims claims = Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); return claims; }} 在jwt该目录下新建JwtTokenFilter过滤器 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisj.config.jwt;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * <p> JwtTokenFilter </p> * <p> Description : JwtTokenFilter </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-26 20:49 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Componentpublic class JwtTokenFilter extends OncePerRequestFilter { public static final String HEADER_STRING = \"Authorization\"; @Autowired private UserDetailsService userDetailsService; @Autowired private JwtTokenTemplate jwtTokenTemplate; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String token = request.getHeader(HEADER_STRING); if (null != token) { String username = jwtTokenTemplate.getUsernameFromToken(token); if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); if (jwtTokenTemplate.validateToken(token, userDetails)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails( request)); SecurityContextHolder.getContext().setAuthentication(authentication); } } } chain.doFilter(request, response); }} 配置Security 在config目录下新建JwtSecurityConfig文件 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisj.config;import com.edurt.sli.slisj.config.jwt.JwtTokenFilter;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.HttpMethod;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;/** * <p> JwtSecurityConfig </p> * <p> Description : JwtSecurityConfig </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-26 20:46 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Configuration@EnableWebSecuritypublic class JwtSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, \"/**\").permitAll() .antMatchers(\"/auth/login\").permitAll() .anyRequest().authenticated(); http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); http.headers().cacheControl(); } @Bean public JwtTokenFilter authenticationTokenFilterBean() { return new JwtTokenFilter(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }} 在config目录下新建JwtUserDetailsService文件 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisj.config;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.stereotype.Service;import java.util.ArrayList;/** * <p> JwtUserDetailsService </p> * <p> Description : JwtUserDetailsService </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-26 20:54 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Servicepublic class JwtUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { if (userName.equals(\"admin\")) { return new User(\"admin\", \"$2a$10$slYQmyNdGzTn7ZLBXBChFOC9f6kFjAqPhccnP6DxlWXx2lPk1C3G6\", new ArrayList<>()); } return null; }} 在resources资源目录下创建一个application.properties的配置文件,内容如下 1server.port=8989 创建授权参数 在/src/main/java/com/edurt/sli/slisj目录下创建param目录,并在该目录下新建JwtParam文件 123456789101112131415161718192021222324252627282930313233343536373839404142/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisj.param;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;/** * <p> JwtParam </p> * <p> Description : JwtParam </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-26 20:59 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Data@ToString@AllArgsConstructor@NoArgsConstructorpublic class JwtParam { private String username; private String password;} 创建授权接口 在/src/main/java/com/edurt/sli/slisj目录下创建controller目录,并在该目录下新建HelloJwtController文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slisj.controller;import com.edurt.sli.slisj.config.JwtUserDetailsService;import com.edurt.sli.slisj.config.jwt.JwtTokenTemplate;import com.edurt.sli.slisj.param.JwtParam;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.web.bind.annotation.*;/** * <p> HelloJwtController </p> * <p> Description : HelloJwtController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-26 20:58 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"auth\")public class HelloJwtController { @Autowired private JwtTokenTemplate jwtTokenTemplate; @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtUserDetailsService userDetailsService; @PostMapping(value = \"login\") public String login(@RequestBody JwtParam body) throws AuthenticationException { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(body.getUsername(), body.getPassword()); Authentication authentication = authenticationManager.authenticate(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication); UserDetails userDetails = userDetailsService.loadUserByUsername(body.getUsername()); return jwtTokenTemplate.generateToken(userDetails); } @GetMapping(value = \"hello\") public String hello() { return \"Hello Jwt!!!\"; }} 校验授权 在控制台输入以下命令(未授权时) 1curl -X GET 'http://localhost:8989/auth/hello' 会出现以下错误信息 1234567{ \"timestamp\": \"2019-11-26T13:05:05.204+0000\", \"status\": 403, \"error\": \"Forbidden\", \"message\": \"Access Denied\", \"path\": \"/auth/hello\"} 提示我们未授权,这时我们使用/auth/login去获得授权的token 1curl -X POST 'http://127.0.0.1:8989/auth/login' --header 'Content-Type: application/json' -d '{\"username\": \"admin\", \"password\": \"password\"}' 返回以下token信息 1eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTU3NTIwNTg4OH0.zc3JTsIHIZSmi-hrgCB1AKrrjVWtnWB4YJjOhzml2k9qRdTGdoDYKM1XriQIAInvIrTDDkpozT4Ny58Wcpm4JA 这时我们使用返回的token进行访问/auth/hello接口获取数据 1curl -X GET 'http://127.0.0.1:8989/auth/hello' --header 'Authorization: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTU3NTIwNTg4OH0.zc3JTsIHIZSmi-hrgCB1AKrrjVWtnWB4YJjOhzml2k9qRdTGdoDYKM1XriQIAInvIrTDDkpozT4Ny58Wcpm4JA' 返回以下信息 1Hello Jwt!!! 此时我们已经完成JWT授权配置 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-security-jwt-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"Security","slug":"Java/Security","permalink":"https://learn-programming.edurt.io/categories/Java/Security/"}],"tags":[{"name":"SpringBoot","slug":"SpringBoot","permalink":"https://learn-programming.edurt.io/tags/SpringBoot/"},{"name":"Security","slug":"Security","permalink":"https://learn-programming.edurt.io/tags/Security/"}]},{"title":"Guice依赖注入(接口多实现)","slug":"Java/Guice/binder-constructor","date":"2020-10-09T10:55:14.000Z","updated":"2020-10-09T10:55:35.286Z","comments":true,"path":"2020/10/09/Java/Guice/binder-constructor.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/09/Java/Guice/binder-constructor.html","excerpt":"","text":"本教程主要详细讲解Guice依赖注入中的特性接口多实现,一般使用到guice的框架的插件机制都是基于该方式实现。 基础环境 技术 版本 Java 1.8+ Guice 4.2.3 初始化项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.guice -DartifactId=guice-binder-multiple -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加Guice依赖 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>learn-integration-guice</artifactId> <groupId>com.edurt.sli.guice</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>guice-binder-multiple</artifactId> <name>Guice依赖注入(接口多实现)</name> <properties> <system.java.version>1.8</system.java.version> <guice.version>4.2.3</guice.version> <lombok.version>1.18.2</lombok.version> </properties> <dependencies> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>${guice.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> guice: guice就是我们核心要使用的依赖 接口多实现注入 如果一个接口有多个实现,如果单单通过@Inject和Module都难以直接实现,但多实现是经常会出现的,Guice提供了其它注入方式来解决此问题。 创建com.edurt.sli.guice.multiple文件夹,并在该文件夹下创建Service接口文件,用于添加我们需要测试的函数 1234567package com.edurt.sli.guice.multiple;public interface Service { void print(String source);} 创建Service接口的实现类JavaService和GuiceService,用于实现接口中的方法,代码如下 12345678910package com.edurt.sli.guice.multiple;public class JavaService implements Service { @Override public void print(String source) { System.out.println(\"Java Service \" + source); } } 12345678910package com.edurt.sli.guice.multiple;public class GuiceService implements Service { @Override public void print(String source) { System.out.println(\"Guice Service \" + source); } } 创建Guice和Java注解类,用于提供guice框架标识 1234567891011121314package com.edurt.sli.guice.multiple;import com.google.inject.BindingAnnotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD, ElementType.PARAMETER})@BindingAnnotationpublic @interface Guice {} 1234567891011121314package com.edurt.sli.guice.multiple;import com.google.inject.BindingAnnotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD, ElementType.PARAMETER})@BindingAnnotationpublic @interface Java {} 创建用于测试注入的应用类Application,代码如下 12345678910111213141516171819202122232425package com.edurt.sli.guice.multiple;import com.google.inject.Guice;import com.google.inject.Inject;public class Application { @Inject @Java public Service java; @Inject @com.edurt.sli.guice.multiple.Guice public Service guice; public static void main(String[] args) { Application application = Guice.createInjector(binder -> { binder.bind(Service.class).annotatedWith(Java.class).to(JavaService.class); binder.bind(Service.class).annotatedWith(com.edurt.sli.guice.multiple.Guice.class).to(GuiceService.class); }).getInstance(Application.class); application.guice.print(\"sss\"); application.java.print(\"sss\"); }} 我们运行程序输出 12Guice Service sssJava Service sss 我们注意看binder的配置中,我们将注解与实际的实现类绑定到了一起,这样就实现了绑定多接口实现的功能。 注意:在本次程序中我们使用的是lambda表达式进行的代码编程,需要jdk1.8及以上版本 静态代码注入 我们如果需要进行静态代码注入服务该怎么写呢?我们参照以前讲解的Guice依赖注入(构造函数注入)资源中,我们创建一个ApplicationStatic类进行static的注入,代码如下 12345678910111213141516171819202122232425package com.edurt.sli.guice.multiple;import com.google.inject.Inject;public class ApplicationStatic { @Inject @Java public static Service java; @Inject @com.edurt.sli.guice.multiple.Guice public static Service guice; public static void main(String[] args) { com.google.inject.Guice.createInjector(binder -> { binder.bind(Service.class).annotatedWith(Java.class).to(JavaService.class); binder.bind(Service.class).annotatedWith(com.edurt.sli.guice.multiple.Guice.class).to(GuiceService.class); binder.requestStaticInjection(ApplicationStatic.class); }); ApplicationStatic.guice.print(\"sss\"); ApplicationStatic.java.print(\"sss\"); }} 我们只需要在binder阶段将我们的主类注入到guice容器中,也就是我们看到的binder.requestStaticInjection(ApplicationStatic.class);代码,运行程序输出以下内容 12Guice Service sssJava Service sss 属性绑定多接口 先看一下多接口绑定的示例 1234567891011121314151617181920212223package com.edurt.sli.guice.multiple;import com.google.inject.Guice;import com.google.inject.Inject;public class ApplicationMultipleProperty { @Inject public Service java; @Inject public Service guice; public static void main(String[] args) { ApplicationMultipleProperty application = Guice.createInjector(binder -> { binder.bind(Service.class).annotatedWith(Java.class).to(JavaService.class); binder.bind(Service.class).annotatedWith(com.edurt.sli.guice.multiple.Guice.class).to(GuiceService.class); }).getInstance(ApplicationMultipleProperty.class); application.guice.print(\"sss\"); application.java.print(\"sss\"); }} 运行以上代码,就会出现以下错误 1234567891011121314151617181920212223Exception in thread \"main\" com.google.inject.ConfigurationException: Guice configuration errors:1) No implementation for com.edurt.sli.guice.multiple.Service was bound. Did you mean? * com.edurt.sli.guice.multiple.Service annotated with interface com.edurt.sli.guice.multiple.Java * com.edurt.sli.guice.multiple.Service annotated with interface com.edurt.sli.guice.multiple.Guice while locating com.edurt.sli.guice.multiple.Service for field at com.edurt.sli.guice.multiple.Application.guice(Application.java:6) while locating com.edurt.sli.guice.multiple.Application2) No implementation for com.edurt.sli.guice.multiple.Service was bound. Did you mean? * com.edurt.sli.guice.multiple.Service annotated with interface com.edurt.sli.guice.multiple.Java * com.edurt.sli.guice.multiple.Service annotated with interface com.edurt.sli.guice.multiple.Guice while locating com.edurt.sli.guice.multiple.Service for field at com.edurt.sli.guice.multiple.Application.java(Application.java:6) while locating com.edurt.sli.guice.multiple.Application2 errors at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1120) at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1078) at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1131) at com.edurt.sli.guice.multiple.Application.main(Application.java:18) 这是因为我们使用了属性绑定了多接口实现,导致guice无法识别具体是哪个实现类,不过guice是强大的这种问题也被考虑到了,只需要使用@Named模板生成注解即可解决,我们姜代码修改为以下内容 123456789101112131415161718192021222324252627package com.edurt.sli.guice.multiple;import com.google.inject.Guice;import com.google.inject.Inject;import com.google.inject.name.Named;import com.google.inject.name.Names;public class ApplicationMultipleProperty { @Inject @Named(\"Java\") public Service java; @Inject @Named(\"Guice\") public Service guice; public static void main(String[] args) { ApplicationMultipleProperty application = Guice.createInjector(binder -> { binder.bind(Service.class).annotatedWith(Names.named(\"Java\")).to(JavaService.class); binder.bind(Service.class).annotatedWith(Names.named(\"Guice\")).to(GuiceService.class); }).getInstance(ApplicationMultipleProperty.class); application.guice.print(\"sss\"); application.java.print(\"sss\"); }} 运行程序后,输出以下结果 12Guice Service sssJava Service sss 这个示例也很好理解,其实我们只是做了两步操作 在绑定实现的时候使用annotatedWith(Names.named("Java"))进行对该服务实现做名称标志 在需要使用服务实现的地方使用@Named("Java")进行服务的引用即可 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/guice-binder-multiple-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"Guice","slug":"Java/Guice","permalink":"https://learn-programming.edurt.io/categories/Java/Guice/"}],"tags":[{"name":"Guice","slug":"Guice","permalink":"https://learn-programming.edurt.io/tags/Guice/"},{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/tags/Java/"}]},{"title":"Guice依赖注入(构造函数注入)","slug":"Java/Guice/guice-binder","date":"2020-10-09T10:53:27.000Z","updated":"2020-10-09T10:53:53.183Z","comments":true,"path":"2020/10/09/Java/Guice/guice-binder.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/09/Java/Guice/guice-binder.html","excerpt":"","text":"本教程主要详细讲解Guice的构造函数注入. 基础环境 技术 版本 Java 1.8+ Guice 4.2.3 初始化项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.guice -DartifactId=guice-binder-constructor -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加Guice依赖 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>learn-integration-guice</artifactId> <groupId>com.edurt.sli.guice</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>guice-binder-constructor</artifactId> <name>Guice依赖注入(构造函数注入)</name> <properties> <system.java.version>1.8</system.java.version> <guice.version>4.2.3</guice.version> <lombok.version>1.18.2</lombok.version> </properties> <dependencies> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>${guice.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> guice: guice就是我们核心要使用的依赖 构造函数注入 在Guice中我们可以通过将需要的实体信息通过构造函数直接注入到我们需要的任意地方,我们通过列举一个例子来实际说明。 创建com.edurt.sli.guice.sample文件夹,并在该文件夹下创建Service接口文件,用于添加我们需要测试的函数 12345678910package com.edurt.sli.guice.sample;import com.google.inject.ImplementedBy;@ImplementedBy(ServiceImpl.class)public interface Service { void print(String source);} 创建Service接口的实现类ServiceImpl,用于实现接口中的方法,代码如下 123456789package com.edurt.sli.guice.sample;public class ServiceImpl implements Service { @Override public void print(String source) { System.out.println(String.format(\"Hello Guice, %s\", source)); }} 创建用于测试注入的应用类Application,代码如下 123456789101112131415161718192021222324package com.edurt.sli.guice.sample;import com.google.inject.Guice;import com.google.inject.Inject;public class Application { private Service service; @Inject public Application(Service service) { this.service = service; } public Service getService() { return service; } public static void main(String[] args) { Application application = Guice.createInjector().getInstance(Application.class); application.service.print(\"Test\"); }} 我们运行程序输出 1Hello Guice, Test 这个示例很好理解,实际就是说我们将Service接口通过@Inject注入到了Application应用中。当然我们通过@ImplementedBy(ServiceImpl.class)实现了类似Service service = new ServiceImpl()的操作,不过每次会生成一个新的实例,如果需要单例模式的话,需要单独操作。 注意:在本次程序中我们并没有通过Module关联到Guice,方便我们快速测试应用等。我们无法通过非Guice容器进行注入,以下就是一个错误的示例static也是无法进行注入的 12345678910111213141516171819package com.edurt.sli.guice.sample;import com.google.inject.Inject;public class ApplicationCustom { @Inject private Service service; public Service getService() { return this.service; } public static void main(String[] args) { ApplicationCustom custom = new ApplicationCustom(); custom.getService().print(\"Test\"); } } 我们运行上述代码,会提示以下错误信息 12Exception in thread \"main\" java.lang.NullPointerException at com.edurt.sli.guice.sample.ApplicationCustom.main(ApplicationCustom.java:16) 这也就说明我们无法在非Guice容器中进行实例注入 多参数注入 上述实例我们只是注入了一个参数,那我们尝试一下多参数注入。 我们先书写另一个需要注入的服务和实现,PrintService代码如下 12345678910package com.edurt.sli.guice.sample;import com.google.inject.ImplementedBy;@ImplementedBy(PrintServiceImpl.class)public interface PrintService { void print();} 实现类ImplementedBy代码如下 12345678910package com.edurt.sli.guice.sample;public class PrintServiceImpl implements PrintService { @Override public void print() { System.out.println(\"print Service\"); }} 该服务我们只提供固定的输出字符串信息print Service,接下来我们进行对多参数注入,ApplicationMultiple代码如下 12345678910111213141516171819202122232425package com.edurt.sli.guice.sample;import com.google.inject.Guice;import com.google.inject.Inject;import lombok.Data;@Datapublic class ApplicationMultiple { private Service service; private PrintService printService; @Inject public ApplicationMultiple(Service service, PrintService printService) { this.service = service; this.printService = printService; } public static void main(String[] args) { ApplicationMultiple multiple = Guice.createInjector().getInstance(ApplicationMultiple.class); multiple.getPrintService().print(); multiple.getService().print(\"Multiple\"); }} 运行程序后,输出以下结果 12print ServiceHello Guice, Multiple 我们使用一个@Inject也能实现多个参数的实例注入,当然还支持Set方式注入,只需要在参数的set方法上增加@Inject注解即可实现,这里我们不多做叙述,可自行实验。 static静态参数注入 我们说过无法注入通过static属性直接进行注入使用,方法总是很多的,Guice提供了以下static注入方式 12345678910111213141516package com.edurt.sli.guice.sample;import com.google.inject.Guice;import com.google.inject.Inject;public class ApplicationStatic { @Inject private static Service service; public static void main(String[] args) { Guice.createInjector(binder -> binder.requestStaticInjection(ApplicationStatic.class)); ApplicationStatic.service.print(\"Static\"); }} 在代码中我们没有向以上两个示例直接使用Guice获取实例,而是使用了binder.requestStaticInjection方式进行了注入,这个是和static属性息息相关的,当我们注入static属性的时候要告知Guice我们具体使用static属性的父类,这样Guice才可以帮我们注入进来。 细心的话会想到我们既然使用binder.requestStaticInjection方式注入static属性,那么非static属性是不是也可以通过类似的方式注入? 答案是可以的,非static的属性我们需要通过binder.requestInjection(Type);方式注入,实例如下: 1234567891011121314151617package com.edurt.sli.guice.sample;import com.google.inject.Guice;import com.google.inject.Inject;public class ApplicationBinder { @Inject private Service service; public static void main(String[] args) { ApplicationBinder applicationBinder = new ApplicationBinder(); Guice.createInjector(binder -> binder.requestInjection(applicationBinder)); applicationBinder.service.print(\"Test\"); }} 当然我们还可以通过Guice.createInjector().injectMembers(new Object());方式注入。 注意我们需要创建一个主类的实例才可以注入,使用ApplicationBinder.class是无法注入的 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/guice-binder-constructor-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"Guice","slug":"Java/Guice","permalink":"https://learn-programming.edurt.io/categories/Java/Guice/"}],"tags":[{"name":"Guice","slug":"Guice","permalink":"https://learn-programming.edurt.io/tags/Guice/"},{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/tags/Java/"}]},{"title":"Guice依赖注入(基础版)","slug":"Java/Guice/binder-multiple","date":"2020-10-09T10:36:09.000Z","updated":"2020-10-09T10:36:48.518Z","comments":true,"path":"2020/10/09/Java/Guice/binder-multiple.html","link":"","permalink":"https://learn-programming.edurt.io/2020/10/09/Java/Guice/binder-multiple.html","excerpt":"","text":"本教程主要详细讲解Guice的一些基本注入方式,通过该简单教程让我们可以快速使用Guice进行简单系统化开发,后续我们会更深入讲解更多模块,如果还不了解Guice大家可以先去网上自行了解一下. 基础环境 技术 版本 Java 1.8+ Guice 4.2.3 初始化项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.guice -DartifactId=guice-basic -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加Guice依赖 123456789101112131415161718192021222324252627282930313233343536373839404142434445<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>learn-integration-guice</artifactId> <groupId>com.edurt.sli.guice</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>guice-basic</artifactId> <name>Guice基础教程</name> <properties> <system.java.version>1.8</system.java.version> <guice.version>4.2.3</guice.version> </properties> <dependencies> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>${guice.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> guice: guice就是我们核心要使用的依赖 Guice的绑定模型 在src/main/java目录下新建com.edurt.sli.guice.sample目录并在该目录下新建GuiceBasicModule类文件,在文件输入以下内容 1234567891011package com.edurt.sli.guice.sample;import com.google.inject.AbstractModule;public class GuiceBasicModule extends AbstractModule { @Override protected void configure() { }} Guice中的绑定模型和Spring中的一样简单,我们通过绑定可以提供给程序任意注入类. 绑定我们需要的Module只需要继承Guice中的com.google.inject.AbstractModule即可,在configure方法中实现我们需要的绑定信息. 在com.edurt.sli.guice.sample目录下构建GuiceBasicService接口类,内容如下 1234567package com.edurt.sli.guice.sample;public interface GuiceBasicService { void print(String output);} 在com.edurt.sli.guice.sample目录下构建GuiceBasicServiceImpl接口实现类,内容如下 123456789package com.edurt.sli.guice.sample;public class GuiceBasicServiceImpl implements GuiceBasicService { public void print(String output) { System.out.println(String.format(\"print %s\", output)); }} 接下来修改GuiceBasicModule将我们定义的服务进行绑定,代码如下 123456789101112package com.edurt.sli.guice.sample;import com.google.inject.AbstractModule;public class GuiceBasicModule extends AbstractModule { @Override protected void configure() { bind(GuiceBasicService.class).to(GuiceBasicServiceImpl.class); }} 这样我们就很快的绑定了一个服务,类似于Spring中的@Bean方式 bind标志我们需要绑定的类,to标志我们绑定的实现类 在com.edurt.sli.guice.sample目录下构建GuiceBasicApplication类文件用于我们测试代码,在文件输入以下内容 123456789101112131415package com.edurt.sli.guice.sample;import com.google.inject.Guice;import com.google.inject.Injector;public class GuiceBasicApplication { public static void main(String[] args) { Injector injector = Guice.createInjector(new GuiceBasicModule()); GuiceBasicService service = injector.getInstance(GuiceBasicService.class); service.print(\"Hello Guice\"); }} 我们运行程序,控制台会输出如下内容: 1print Hello Guice 构造函数绑定 首先我们构建用于注入的服务类,代码如下 123456@ImplementedBy(ConstructorServiceImpl.class)interface ConstructorService { void print();} @ImplementedBy告知我们程序我们的接口具体实现类,Guice会帮我们做自动实例化 服务实现类,我们打印简单的字符串,代码如下 12345678class ConstructorServiceImpl implements ConstructorService { @Override public void print() { System.out.println(\"Hello Guice By Constructor\"); }} 使用构造函数进行注入,代码如下 12345678910111213141516171819public class ConstructorApplication { private ConstructorService service; @Inject public ConstructorApplication(ConstructorService service) { this.service = service; } public ConstructorService getService() { return service; } public static void main(String[] args) { ConstructorApplication instance = Guice.createInjector().getInstance(ConstructorApplication.class); instance.getService().print(); }} 我们运行程序,控制台会输出如下内容: 1Hello Guice By Constructor 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/guice-binder-1.0.0.jar 源码地址 GitHub","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"Guice","slug":"Java/Guice","permalink":"https://learn-programming.edurt.io/categories/Java/Guice/"}],"tags":[{"name":"Guice","slug":"Guice","permalink":"https://learn-programming.edurt.io/tags/Guice/"},{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/tags/Java/"}]},{"title":"整合Redis教程(JPA实战版)","slug":"Java/DataJPA/datajpa-redis-datajpa","date":"2020-05-31T05:12:07.000Z","updated":"2020-10-09T10:35:01.414Z","comments":true,"path":"2020/05/31/Java/DataJPA/datajpa-redis-datajpa.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/31/Java/DataJPA/datajpa-redis-datajpa.html","excerpt":"","text":"本教程主要详细讲解Spring Data Redis,它向Redis提供Spring Data平台的抽象. Redis由基于key/value库的数据结构存数,以持久保存数据,并可用作数据库,缓存,消息代理等。 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x DataJPA 2.x.x Jedis 2.9.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slidra -DartifactId=spring-learn-integration-datajpa-redis-action -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加redis的支持 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-datajpa</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-datajpa-redis-action</artifactId> <name>Spring DataJPA Redis教程(DataJPA实战版)</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${dependency.jedis.version}</version> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>${dependency.lettuce.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-boot-starter-data-redis整合Redis需要的依赖包,或者单独使用spring-data-redis和jedis依赖包 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootDataJPARedisActionIntegration </p> * <p> Description : SpringBootDataJPARedisActionIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 10:17 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootDataJPARedisActionIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootDataJPARedisActionIntegration.class, args); }} 配置支持Redis 在resources资源目录下创建一个application.properties的配置文件,内容如下 1234567spring.redis.host=localhostspring.redis.port=6379spring.redis.database=0spring.redis.jedis.pool.max-active=8spring.redis.jedis.pool.max-wait=1msspring.redis.lettuce.pool.max-active=8spring.redis.jedis.pool.min-idle=0 操作Redis数据 在/src/main/java/com/edurt/sli/slidra目录下创建model目录,并在该目录下新建RedisModel文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;import org.springframework.data.annotation.Id;import org.springframework.data.redis.core.RedisHash;/** * <p> RedisModel </p> * <p> Description : RedisModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 10:19 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RedisHash(value = \"Redis\")@Data@ToString@AllArgsConstructor@NoArgsConstructorpublic class RedisModel { @Id private String id; private String name;} @RedisHash为每个数据库创建域类的空子类。 @Id注解的属性和被命名为id的属性会被当作标识属性 在/src/main/java/com/edurt/sli/slidra目录下创建repository目录,并在该目录下新建RedisSupport文件 12345678910111213141516171819202122232425262728293031323334/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.repository;import com.edurt.sli.slidra.model.RedisModel;import org.springframework.data.repository.CrudRepository;import org.springframework.stereotype.Repository;/** * <p> RedisSupport </p> * <p> Description : RedisSupport </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 10:20 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Repositorypublic interface RedisSupport extends CrudRepository<RedisModel, String> {} 在CrudRepository中提供了一些基础的增删改查的功能. 测试增删改查的功能 在/src/main/java/com/edurt/sli/slidra目录下创建controller目录,并在该目录下新建RedisController文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.controller;import com.edurt.sli.slidra.model.RedisModel;import com.edurt.sli.slidra.repository.RedisSupport;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;/** * <p> RedisController </p> * <p> Description : RedisController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 10:21 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"redis\")public class RedisController { @Autowired private RedisSupport support; @GetMapping public Object get() { return this.support.findAll(); } @PostMapping public Object post(@RequestBody RedisModel mode) { return this.support.save(mode); } @PutMapping public Object put(@RequestBody RedisModel mode) { return this.support.save(mode); } @DeleteMapping public Object delete(@RequestParam String id) { this.support.deleteById(id); return \"SUCCESS\"; }} 测试基本的增删改查功能 Redis数据分页功能 修改RedisSupport文件将继承的CrudRepository修改为PagingAndSortingRepository 1234567891011121314151617181920212223242526272829303132333435/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.repository;import com.edurt.sli.slidra.model.RedisModel;import org.springframework.data.repository.PagingAndSortingRepository;import org.springframework.stereotype.Repository;/** * <p> RedisSupport </p> * <p> Description : RedisSupport </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 10:20 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Repositorypublic interface RedisSupport extends PagingAndSortingRepository<RedisModel, String> {} 修改RedisController增加以下代码 12345@GetMapping(value = \"page\")public Object get(@RequestParam Integer page, @RequestParam Integer size) { return this.support.findAll(PageRequest.of(page, size));} 重启服务器测试分页功能 12> $ curl -X GET 'http://localhost:8080/redis/page?page=0&size=10'{\"content\":[{\"id\":\"1\",\"name\":\"Hello Redis\"}],\"pageable\":{\"sort\":{\"sorted\":false,\"unsorted\":true},\"offset\":0,\"pageSize\":10,\"pageNumber\":0,\"unpaged\":false,\"paged\":true},\"last\":true,\"totalPages\":1,\"totalElements\":1,\"size\":10,\"number\":0,\"first\":true,\"numberOfElements\":1,\"sort\":{\"sorted\":false,\"unsorted\":true}}% 由于jpa分页默认是从0开始,所以我们首页需要传递0 Redis数据清理 在DataJpa中我们设置对Redis数据清理只需要设置过期时间即可,可以分为两种方式设置(注意单位是按照秒计算) 全局数据模型过期时间设置 修改RedisModel,在RedisHash增加属性timeToLive 12345678910111213141516171819202122232425262728293031323334353637383940414243444546/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;import org.springframework.data.annotation.Id;import org.springframework.data.redis.core.RedisHash;/** * <p> RedisModel </p> * <p> Description : RedisModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 10:19 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RedisHash(value = \"Redis\", timeToLive = 60)@Data@ToString@AllArgsConstructor@NoArgsConstructorpublic class RedisModel { @Id private String id; private String name;} 重启服务器添加数据等待1分钟进行数据查询 对数据增加过期时间字段设置 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;import org.springframework.data.annotation.Id;import org.springframework.data.redis.core.RedisHash;import org.springframework.data.redis.core.TimeToLive;import java.util.concurrent.TimeUnit;/** * <p> RedisModel </p> * <p> Description : RedisModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 10:19 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RedisHash(value = \"Redis\")@Data@ToString@AllArgsConstructor@NoArgsConstructorpublic class RedisModel { @Id private String id; private String name; @TimeToLive(unit = TimeUnit.SECONDS) private Long timeout;} 注意: 使用RedisHash要注意数据过期后,jpa得分页查询会错误.redis数据过期,在redis底层是将数据删除的,因为在jpa工具中使用集成reids会做一层目录关系,这个关系是jpa维护的,但是数据清理过期是redis维护,完全两套隔离的,当redis清理数据后,并没有去清理jpa维护的关系,所以jpa中查询数据是有数据的,但是实际得详情数据已经被redis清理了,故关联不上返回的就是null,导致实际数据和jpa分页得数据不一致. 官方解释为: 将EXPIRE执行相应的命令。除了保留原始副本外,幻影副本还将保留在Redis中,并设置为在原始副本后五分钟到期。这样做是为了使存储库支持能够发布RedisKeyExpiredEvent,ApplicationEventPublisher只要密钥过期,即使原始值已被删除,Spring仍将过期值保存在Spring中。在使用Spring Data Redis存储库的所有已连接应用程序上都会收到到期事件。 使用监听事件解决数据过期分页问题 在/src/main/java/com/edurt/sli/slidra目录下创建config目录,并在该目录下新建RedisListenerConfig文件 1234567891011121314151617181920212223242526272829303132333435363738394041424344/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.listener.RedisMessageListenerContainer;/** * <p> RedisListenerConfig </p> * <p> Description : RedisListenerConfig </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 14:02 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Configurationpublic class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory);// container.addMessageListener(new RedisExpiredListener(), new PatternTopic(\"__keyevent@0__:expired\")); return container; }} 在config目录下新建RedisKeyExpirationListener监听文件 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidra.config;import com.edurt.sli.slidra.model.RedisModel;import com.edurt.sli.slidra.repository.RedisSupport;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.connection.Message;import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;import org.springframework.data.redis.listener.RedisMessageListenerContainer;import org.springframework.stereotype.Component;/** * <p> RedisKeyExpirationListener </p> * <p> Description : RedisKeyExpirationListener </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-05 12:05 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Componentpublic class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { @Autowired private RedisSupport support; public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } /** * 针对redis数据失效事件,进行数据处理 * * @param message message.toString()获取失效的key * @param pattern */ @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = message.toString(); // 获得key之后可以做数据删除操作 // expiredKey格式为value:key }} 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-datajpa-redis-action-1.0.0.jar 源码地址 GitHub Gitee","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"DataJPA","slug":"Java/DataJPA","permalink":"https://learn-programming.edurt.io/categories/Java/DataJPA/"}],"tags":[{"name":"DataJPA","slug":"DataJPA","permalink":"https://learn-programming.edurt.io/tags/DataJPA/"},{"name":"Redis","slug":"Redis","permalink":"https://learn-programming.edurt.io/tags/Redis/"}]},{"title":"整合Redis教程(Template版)","slug":"Java/DataJPA/datajpa-redis-template","date":"2020-05-31T05:10:19.000Z","updated":"2020-10-09T10:35:01.409Z","comments":true,"path":"2020/05/31/Java/DataJPA/datajpa-redis-template.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/31/Java/DataJPA/datajpa-redis-template.html","excerpt":"","text":"本教程主要详细讲解Spring Data Redis,它向Redis提供Spring Data平台的抽象. Redis由基于key/value库的数据结构存数,以持久保存数据,并可用作数据库,缓存,消息代理等。 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x DataJPA 2.x.x Jedis 2.9.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slidrt -DartifactId=spring-learn-integration-datajpa-redis-template -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加redis的支持 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-datajpa</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-datajpa-redis-template</artifactId> <name>Spring DataJPA Redis教程(Template版)</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${dependency.spring.data.jpa.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${dependency.jedis.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-data-redis整合Redis需要的依赖包 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidrt;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootDataJPARedisTemplateIntegration </p> * <p> Description : SpringBootDataJPARedisTemplateIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 14:24 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootDataJPARedisTemplateIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootDataJPARedisTemplateIntegration.class, args); }} 配置支持Redis 在/src/main/java/com/edurt/sli/slidr目录下创建config目录,并在该目录下新建RedisConfig文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidrt.config;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisStandaloneConfiguration;import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Component;/** * <p> RedisConfig </p> * <p> Description : RedisConfig </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 14:26 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Component@Configuration@ConfigurationProperties(prefix = \"custom.redis\")@Data@AllArgsConstructor@NoArgsConstructorpublic class RedisConfig { private String server; // redis服务器地址 private Integer port; // redis服务器地址 @Qualifier(value = \"redisTemplate\") @Bean public StringRedisTemplate redisTemplate() { StringRedisTemplate template = new StringRedisTemplate(); JedisConnectionFactory factory = jedisConnectionFactory(); template.setConnectionFactory(factory); return template; } @Bean public JedisConnectionFactory jedisConnectionFactory() { JedisConnectionFactory factory = new JedisConnectionFactory(new RedisStandaloneConfiguration(server, port)); factory.afterPropertiesSet(); return factory; }} 在resources资源目录下创建一个application.properties的配置文件,内容如下 12custom.redis.server=localhostcustom.redis.port=6379 操作Redis数据 在/src/main/java/com/edurt/sli/slidrt目录下创建model目录,并在该目录下新建RedisTemplateModel文件 123456789101112131415161718192021222324252627282930313233343536373839404142/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidrt.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;/** * <p> RedisTemplateModel </p> * <p> Description : RedisTemplateModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 14:35 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Data@ToString@AllArgsConstructor@NoArgsConstructorpublic class RedisTemplateModel { private String id; private String name;} 测试增删改查的功能 在/src/main/java/com/edurt/sli/slidrt目录下创建controller目录,并在该目录下新建RedisTemplateController文件 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidrt.controller;import com.edurt.sli.slidrt.model.RedisTemplateModel;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.web.bind.annotation.*;/** * <p> RedisTemplateController </p> * <p> Description : RedisTemplateController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 14:38 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"redis/template\")public class RedisTemplateController { @Autowired private StringRedisTemplate stringRedisTemplate; private static String KEY = \"RedisTemplate\"; @GetMapping public Object get() { return this.stringRedisTemplate.opsForHash().entries(KEY); } @PostMapping public Object post(@RequestBody RedisTemplateModel model) { this.stringRedisTemplate.opsForHash().put(KEY, model.getId(), model.getName()); return \"SUCCESS\"; } @PutMapping public Object put(@RequestBody RedisTemplateModel model) { this.stringRedisTemplate.opsForHash().put(KEY, model.getId(), model.getName()); return \"SUCCESS\"; } @DeleteMapping public Object delete(@RequestParam String id) { this.stringRedisTemplate.opsForHash().delete(KEY, id); return \"SUCCESS\"; }} 添加数据 12shicheng@localhost ~> curl -X POST http://localhost:8080/redis/template -H 'Content-Type:application/json' -d '{\"id\": \"1\", \"name\": \"Hello Redis\"}'SUCCESS⏎ 修改数据 12shicheng@localhost ~> curl -X PUT http://localhost:8080/redis/template -H 'Content-Type:application/json' -d '{\"id\": \"1\", \"name\": \"Hello Redis Modfiy\"}'SUCCESS⏎ 获取数据 12shicheng@shichengdeMacBook-Pro ~> curl -X GET http://localhost:8080/redis/template[{\"id\":\"1\",\"name\":\"Hello Redis Modfiy\"}]⏎ 删除数据 12shicheng@shichengdeMacBook-Pro ~> curl -X DELETE 'http://localhost:8080/redis/template?id=1'SUCCESS⏎ 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar spring-learn-integration-datajpa/spring-learn-integration-datajpa-redis-template/target/spring-learn-integration-datajpa-redis-template-1.0.0.jar 源码地址 GitHub Gitee","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"DataJPA","slug":"Java/DataJPA","permalink":"https://learn-programming.edurt.io/categories/Java/DataJPA/"}],"tags":[{"name":"DataJPA","slug":"DataJPA","permalink":"https://learn-programming.edurt.io/tags/DataJPA/"},{"name":"Redis","slug":"Redis","permalink":"https://learn-programming.edurt.io/tags/Redis/"}]},{"title":"整合Redis教程(基础版)","slug":"Java/DataJPA/datajpa-redis-basic","date":"2020-05-31T05:09:15.000Z","updated":"2020-10-09T10:35:01.399Z","comments":true,"path":"2020/05/31/Java/DataJPA/datajpa-redis-basic.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/31/Java/DataJPA/datajpa-redis-basic.html","excerpt":"","text":"本教程主要详细讲解Spring Data Redis,它向Redis提供Spring Data平台的抽象. Redis由基于key/value库的数据结构存数,以持久保存数据,并可用作数据库,缓存,消息代理等。 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x DataJPA 2.x.x Jedis 2.9.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slidr -DartifactId=spring-learn-integration-datajpa-redis -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加redis的支持 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-datajpa</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-datajpa-redis</artifactId> <name>Spring DataJPA Redis教程(基础版)</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${dependency.jedis.version}</version> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>${dependency.lettuce.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-boot-starter-data-redis整合Redis需要的依赖包,或者单独使用spring-data-redis和jedis依赖包 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidr;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootDataJPARedisIntegration </p> * <p> Description : SpringBootDataJPARedisIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 00:44 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootDataJPARedisIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootDataJPARedisIntegration.class, args); }} 配置支持Redis 在resources资源目录下创建一个application.properties的配置文件,内容如下 1234567spring.redis.host=localhostspring.redis.port=6379spring.redis.database=0spring.redis.jedis.pool.max-active=8spring.redis.jedis.pool.max-wait=1msspring.redis.lettuce.pool.max-active=8spring.redis.jedis.pool.min-idle=0 操作Redis数据 在/src/main/java/com/edurt/sli/slidr目录下创建model目录,并在该目录下新建RedisModel文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidr.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;import org.springframework.data.annotation.Id;import org.springframework.data.redis.core.RedisHash;/** * <p> RedisModel </p> * <p> Description : RedisModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 01:06 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RedisHash(value = \"Redis\")@Data@ToString@AllArgsConstructor@NoArgsConstructorpublic class RedisModel { @Id private String id; private String name;} @RedisHash为每个数据库创建域类的空子类。 @Id注解的属性和被命名为id的属性会被当作标识属性 在/src/main/java/com/edurt/sli/slidr目录下创建repository目录,并在该目录下新建RedisSupport文件 12345678910111213141516171819202122232425262728293031323334/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidr.repository;import com.edurt.sli.slidr.model.RedisModel;import org.springframework.data.repository.CrudRepository;import org.springframework.stereotype.Repository;/** * <p> RedisSupport </p> * <p> Description : RedisSupport </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 00:59 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Repositorypublic interface RedisSupport extends CrudRepository<RedisModel, String> {} 在CrudRepository中提供了一些基础的增删改查的功能. 测试增删改查的功能 在/src/main/java/com/edurt/sli/slidr目录下创建controller目录,并在该目录下新建RedisController文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidr.controller;import com.edurt.sli.slidr.model.RedisModel;import com.edurt.sli.slidr.repository.RedisSupport;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;/** * <p> RedisController </p> * <p> Description : RedisController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-06-14 01:05 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"redis\")public class RedisController { @Autowired private RedisSupport support; @GetMapping public Object get() { return this.support.findAll(); } @PostMapping public Object post(@RequestBody RedisModel mode) { return this.support.save(mode); } @PutMapping public Object put(@RequestBody RedisModel mode) { return this.support.save(mode); } @DeleteMapping public Object delete(@RequestParam String id) { this.support.deleteById(id); return \"SUCCESS\"; }} 添加数据 12shicheng@shichengdeMacBook-Pro ~> curl -X POST http://localhost:8080/redis -H 'Content-Type:application/json' -d '{\"id\": \"1\", \"name\": \"Hello Redis\"}'{\"id\":\"1\",\"name\":\"Hello Redis\"}⏎ 修改数据 12shicheng@shichengdeMacBook-Pro ~> curl -X PUT http://localhost:8080/redis -H 'Content-Type:application/json' -d '{\"id\": \"1\", \"name\": \"Hello Redis Modfiy\"}'{\"id\":\"1\",\"name\":\"Hello Redis Modfiy\"}⏎ 获取数据 12shicheng@shichengdeMacBook-Pro ~> curl -X GET http://localhost:8080/redis[{\"id\":\"1\",\"name\":\"Hello Redis Modfiy\"}]⏎ 删除数据 12shicheng@shichengdeMacBook-Pro ~> curl -X DELETE 'http://localhost:8080/redis?id=1'SUCCESS⏎ 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-datajpa-redis-1.0.0.jar 源码地址 GitHub Gitee","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"DataJPA","slug":"Java/DataJPA","permalink":"https://learn-programming.edurt.io/categories/Java/DataJPA/"}],"tags":[{"name":"DataJPA","slug":"DataJPA","permalink":"https://learn-programming.edurt.io/tags/DataJPA/"},{"name":"Redis","slug":"Redis","permalink":"https://learn-programming.edurt.io/tags/Redis/"}]},{"title":"整合MongoDB教程(Template版)","slug":"Java/DataJPA/datajpa-mongodb-template","date":"2020-05-09T07:39:43.000Z","updated":"2020-10-09T10:35:01.394Z","comments":true,"path":"2020/05/09/Java/DataJPA/datajpa-mongodb-template.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/09/Java/DataJPA/datajpa-mongodb-template.html","excerpt":"","text":"本教程主要详细讲解Spring Data MongoDB,它向MongoDB提供Spring Data平台的抽象. MongoDB是基于文档的存储,以持久保存数据,并可用作数据库,缓存,消息代理等. 我们通过以下几个步骤进行讲解: 基础环境 创建项目 配置支持MongoDB 操作JDBC数据 操作MongoDB数据 打包文件部署 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x DataJPA 2.x.x MongoDB 3.6.3-cmongo- 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slidmt -DartifactId=spring-learn-integration-datajpa-mongodb-template -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加mongodb的支持 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-datajpa</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-datajpa-mongodb-template</artifactId> <name>Spring DataJPA MongoDB教程(Template版)</name> <properties> <spring.data.mongodb.version>2.2.0.RELEASE</spring.data.mongodb.version> </properties> <dependencies> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>${spring.data.mongodb.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-data-mongodb整合MongoDB需要的依赖包 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidmt;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootDataJPAMongoDBTemplateIntegration </p> * <p> Description : SpringBootDataJPAMongoDBTemplateIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-21 11:26 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootDataJPAMongoDBTemplateIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootDataJPAMongoDBTemplateIntegration.class, args); }} 配置支持MongoDB 在/src/main/java/com/edurt/sli/slidmt目录下创建config目录,并在该目录下新建MongoDBConfig文件 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidmt.config;import com.mongodb.MongoClient;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.stereotype.Component;/** * <p> MongoDBConfig </p> * <p> Description : MongoDBConfig </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-21 11:28 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Component@Configuration@ConfigurationProperties(prefix = \"custom.mongodb\")@Data@AllArgsConstructor@NoArgsConstructorpublic class MongoDBConfig { private String server; // mongodb服务器地址 private Integer port; // mongodb服务器地址端口 private String database; // mongodb访问的数据库 @Bean public MongoClient mongoClient() { return new MongoClient(server, port); } @Bean public MongoTemplate mongoTemplate() { return new MongoTemplate(mongoClient(), database); }} 在resources资源目录下创建一个application.properties的配置文件,内容如下 123custom.mongodb.server=localhostcustom.mongodb.port=27017custom.mongodb.database=test 操作MongoDB数据 在/src/main/java/com/edurt/sli/slidmt目录下创建model目录,并在该目录下新建MongoDBModel文件 12345678910111213141516171819202122232425262728293031323334353637383940414243/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidmt.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;/** * <p> MongoDBModel </p> * <p> Description : MongoDBModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-21 11:42 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Data@ToString@AllArgsConstructor@NoArgsConstructorpublic class MongoDBModel { private String id; private String title; private String context;} 测试增删改查的功能 在/src/main/java/com/edurt/sli/slidmt目录下创建controller目录,并在该目录下新建MongoDbController文件 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidmt.controller;import com.edurt.sli.slidmt.model.MongoDBModel;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.data.mongodb.core.query.Criteria;import org.springframework.data.mongodb.core.query.Query;import org.springframework.data.mongodb.core.query.Update;import org.springframework.web.bind.annotation.*;/** * <p> MongoDbController </p> * <p> Description : MongoDbController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-21 11:44 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"mongodb/template\")public class MongoDbController { @Autowired private MongoTemplate mongoTemplate; @GetMapping public Object get() { return this.mongoTemplate.findOne(Query.query(Criteria.where(\"title\").is(\"Hello MongoDB\")), MongoDBModel.class); } @PostMapping public Object post(@RequestBody MongoDBModel model) { return this.mongoTemplate.save(model); } @PutMapping public Object put(@RequestBody MongoDBModel model) { Query query = new Query(Criteria.where(\"title\").is(\"Hello MongoDB\")); Update update = new Update().set(\"title\", model.getTitle()); return this.mongoTemplate.findAndModify(query, update, MongoDBModel.class); } @DeleteMapping public Object delete(@RequestParam String id) { return this.mongoTemplate.remove(Query.query(Criteria.where(\"id\").is(id))); }} 添加数据 12shicheng@shichengdeMacBook-Pro ~> curl -X POST http://localhost:8080/mongodb/template -H 'Content-Type:application/json' -d '{\"title\": \"HelloMongoDB\", \"context\": \"我是SpringBoot整合MongoDB示例\"}'{\"id\":\"5dad2d4ea479fc579f298545\",\"title\":\"HelloMongoDB\",\"context\":\"我是SpringBoot整合MongoDB示例\"}⏎ 修改数据 12shicheng@shichengdeMacBook-Pro ~> curl -X PUT http://localhost:8080/mongodb/template -H 'Content-Type:application/json' -d '{\"title\": \"HelloMongoDBModfiy\", \"context\": \"我是SpringBoot整合MongoDB示例\"}'{\"id\":\"5dad2d4ea479fc579f298545\",\"title\":\"HelloMongoDBModfiy\",\"context\":\"我是SpringBoot整合MongoDB示例\"}⏎ 获取数据 12shicheng@shichengdeMacBook-Pro ~> curl -X GET http://localhost:8080/mongodb/template{\"id\":\"5dad2d4ea479fc579f298545\",\"title\":\"HelloMongoDBModfiy\",\"context\":\"我是SpringBoot整合MongoDB示例\"}⏎ 删除数据 12shicheng@shichengdeMacBook-Pro ~> curl -X DELETE 'http://localhost:8080/mongodb/template?title=HelloMongoDB'SUCCESS⏎ 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-datajpa-mongodb-template-1.0.0.jar 源码地址 GitHub Gitee","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"DataJPA","slug":"Java/DataJPA","permalink":"https://learn-programming.edurt.io/categories/Java/DataJPA/"}],"tags":[{"name":"DataJPA","slug":"DataJPA","permalink":"https://learn-programming.edurt.io/tags/DataJPA/"},{"name":"MongoDB","slug":"MongoDB","permalink":"https://learn-programming.edurt.io/tags/MongoDB/"}]},{"title":"整合MongoDB教程(基础版)","slug":"Java/DataJPA/datajpa-mongodb-basic","date":"2020-05-08T06:42:05.000Z","updated":"2020-10-09T10:35:01.404Z","comments":true,"path":"2020/05/08/Java/DataJPA/datajpa-mongodb-basic.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/08/Java/DataJPA/datajpa-mongodb-basic.html","excerpt":"","text":"本教程主要详细讲解Spring Data MongoDB,它向MongoDB提供Spring Data平台的抽象. MongoDB是基于文档的存储,以持久保存数据,并可用作数据库,缓存,消息代理等. 我们通过以下几个步骤进行讲解: 基础环境 创建项目 配置支持MongoDB 操作JDBC数据 操作MongoDB数据 打包文件部署 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x DataJPA 2.x.x MongoDB 3.6.3-cmongo- 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slidm -DartifactId=spring-learn-integration-datajpa-mongodb -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加mongodb的支持 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-datajpa</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-datajpa-mongodb</artifactId> <name>Spring DataJPA MongoDB教程(基础版)</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-boot-starter-data-mongodb整合MongoDB需要的依赖包 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidm;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootDataJPAMongoDBIntegration </p> * <p> Description : SpringBootDataJPAMongoDBIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-18 10:44 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootDataJPAMongoDBIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootDataJPAMongoDBIntegration.class, args); } } 配置支持MongoDB 在resources资源目录下创建一个application.properties的配置文件,内容如下 123spring.data.mongodb.host=10.100.10.4spring.data.mongodb.port=27017spring.data.mongodb.database=test 操作MongoDB数据 在/src/main/java/com/edurt/sli/slidm目录下创建model目录,并在该目录下新建MongoDBModel文件 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidm.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;import org.springframework.data.annotation.Id;import org.springframework.data.mongodb.core.mapping.Document;/** * <p> MongoDBModel </p> * <p> Description : MongoDBModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-18 10:51 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Data@ToString@AllArgsConstructor@NoArgsConstructor@Documentpublic class MongoDBModel { @Id private String id; private String title; private String context;} @Document相当于Hibernate实体的@Entity/@Table(必写) @Id相当于Hibernate实体的主键@Id注解(必写) 在/src/main/java/com/edurt/sli/slidm目录下创建repository目录,并在该目录下新建MongoDBSupport文件 123456789101112131415161718192021222324252627282930313233package com.edurt.sli.slidm.repository; /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */import com.edurt.sli.slidm.model.MongoDBModel;import org.springframework.data.mongodb.repository.MongoRepository;import org.springframework.stereotype.Repository;/** * <p> MongoDBSupport </p> * <p> Description : MongoDBSupport </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-18 10:54 </p> * <p> Author Eamil: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Repositorypublic interface MongoDBSupport extends MongoRepository<MongoDBModel, String> {} 在MongoRepository中提供了一些基础的增删改查以及分页的功能. 测试增删改查的功能 在/src/main/java/com/edurt/sli/slidm目录下创建controller目录,并在该目录下新建MongoDbController文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidm.controller;import com.edurt.sli.slidm.model.MongoDBModel;import com.edurt.sli.slidm.repository.MongoDBSupport;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;/** * <p> MongoDbController </p> * <p> Description : MongoDbController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-10-18 10:57 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"mongodb\")public class MongoDbController { @Autowired private MongoDBSupport support; @GetMapping public Object get() { return this.support.findAll(); } @PostMapping public Object post(@RequestBody MongoDBModel mode) { return this.support.save(mode); } @PutMapping public Object put(@RequestBody MongoDBModel mode) { return this.support.save(mode); } @DeleteMapping public Object delete(@RequestParam String id) { this.support.deleteById(id); return \"SUCCESS\"; }} 添加数据 12shicheng@shichengdeMacBook-Pro ~> curl -X POST http://localhost:8080/mongodb -H 'Content-Type:application/json' -d '{\"title\": \"Hello MongoDB\", \"context\": \"我是SpringBoot整合MongoDB示例\"}'{\"id\":null,\"title\":\"Hello MongoDB\",\"context\":\"我是SpringBoot整合MongoDB示例\"}⏎ 修改数据 12shicheng@shichengdeMacBook-Pro ~> curl -X PUT http://localhost:8080/mongodb -H 'Content-Type:application/json' -d '{\"id\": 1,\"title\": \"Hello MongoDB\", \"context\": \"我是SpringBoot整合MongoDB示例,Modfiy\"}'{\"id\":1,\"title\":\"Hello MongoDB\",\"context\":\"我是SpringBoot整合MongoDB示例,Modfiy\"}⏎ 获取数据 12shicheng@shichengdeMacBook-Pro ~> curl -X GET http://localhost:8080/mongodb{\"content\":[{\"id\":null,\"title\":\"Hello MongoDB\",\"context\":\"我是SpringBoot整合MongoDB示例,Modfiy\"},{\"id\":1,\"title\":\"Hello MongoDB\",\"context\":\"我是SpringBoot整合MongoDB示例,Modfiy\"}],\"pageable\":{\"sort\":{\"sorted\":false,\"unsorted\":true},\"offset\":0,\"pageSize\":2,\"pageNumber\":0,\"paged\":true,\"unpaged\":false},\"facets\":[],\"aggregations\":null,\"scrollId\":null,\"totalElements\":2,\"totalPages\":1,\"size\":2,\"number\":0,\"numberOfElements\":2,\"first\":true,\"sort\":{\"sorted\":false,\"unsorted\":true},\"last\":true}⏎ 删除数据 12shicheng@shichengdeMacBook-Pro ~> curl -X DELETE 'http://localhost:8080/mongodb?id=1'SUCCESS⏎ 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-datajpa-mongodb-1.0.0.jar 源码地址 GitHub Gitee","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"DataJPA","slug":"Java/DataJPA","permalink":"https://learn-programming.edurt.io/categories/Java/DataJPA/"}],"tags":[{"name":"DataJPA","slug":"DataJPA","permalink":"https://learn-programming.edurt.io/tags/DataJPA/"},{"name":"MongoDB","slug":"MongoDB","permalink":"https://learn-programming.edurt.io/tags/MongoDB/"}]},{"title":"整合JDBC教程(基础版)","slug":"Java/DataJPA/datajpa-jdbc-basic","date":"2020-05-08T06:38:26.000Z","updated":"2020-10-09T10:35:01.382Z","comments":true,"path":"2020/05/08/Java/DataJPA/datajpa-jdbc-basic.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/08/Java/DataJPA/datajpa-jdbc-basic.html","excerpt":"","text":"本教程主要详细讲解SpringBoot整合JPA进行JDBC对数据库的各种操作. 我们通过以下几个步骤进行讲解: 基础环境 创建项目 配置支持JDBC 操作JDBC数据 JDBC数据分页功能 JDBC数据排序功能 JDBC数据排序分页组合功能 自动创建SQL 打印SQL日志 打包文件部署 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x DataJPA 2.x.x MySQL 5.x.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slidj -DartifactId=spring-learn-integration-datajpa-jdbc -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加jdbc的支持 1234567891011121314151617181920212223242526272829303132333435363738394041<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-datajpa</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-datajpa-jdbc</artifactId> <name>Spring DataJPA JDBC教程(基础版)</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${dependency.mysql.version}</version> </dependency> </dependencies></project> spring-boot-starter-data-jpa整合JDBC需要的依赖包 mysql-connector-java整合JDBC需要连接MySQL依赖包 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidj;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootDataJPAJDBC </p> * <p> Description : SpringBootDataJPAJDBC </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-13 20:23 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootDataJPAJDBCIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootDataJPAJDBCIntegration.class, args); }} 配置支持JDBC 在resources资源目录下创建一个application.properties的配置文件,内容如下 1234spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/test?charset=utf8mb4&useSSL=falsespring.datasource.username=rootspring.datasource.password=123456 操作JDBC数据 在/src/main/java/com/edurt/sli/slidj目录下创建model目录,并在该目录下新建JDBCModel文件 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidj.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;import javax.persistence.*;/** * <p> JDBCModel </p> * <p> Description : JDBCModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-13 20:39 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Data@ToString@AllArgsConstructor@NoArgsConstructor@Entity@Table(name = \"jdbc\")public class JDBCModel { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = \"id\") private Long id; private String name; @Column(length = 64) private String context;} @Entity必选的注解,声明这个类对应了一个数据库表 @Table 可选的注解.声明了数据库实体对应的表信息.包括表名称、索引信息等,如果没有指定,则表名和实体的名称保持一致 @Id注解的属性和被命名为id的属性会被当作标识属性 @Column声明实体属性的表字段的定义.默认的实体每个属性都对应了表的一个字段.字段的名称默认和属性名称保持一致(并不一定相等).字段的类型根据实体属性类型自动推断.如果不这么声明,则系统会采用 255 作为该字段的长度 在/src/main/java/com/edurt/sli/slidj目录下创建repository目录,并在该目录下新建JDBCSupport文件 12345678910111213141516171819202122232425262728293031323334/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidj.repository;import com.edurt.sli.slidj.model.JDBCModel;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;/** * <p> JDBCSupport </p> * <p> Description : JDBCSupport </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-13 20:45 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Repositorypublic interface JDBCSupport extends JpaRepository<JDBCModel, Long> {} 在JpaRepository中提供了一些基础的增删改查的功能以及分页等 测试增删改查的功能 在/src/main/java/com/edurt/sli/slidj目录下创建controller目录,并在该目录下新建JDBCController文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slidj.controller;import com.edurt.sli.slidj.model.JDBCModel;import com.edurt.sli.slidj.repository.JDBCSupport;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;/** * <p> JDBCController </p> * <p> Description : JDBCController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-11-13 20:47 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"jdbc\")public class JDBCController { @Autowired private JDBCSupport support; @GetMapping public Object get() { return this.support.findAll(); } @PostMapping public Object post(@RequestBody JDBCModel mode) { return this.support.save(mode); } @PutMapping public Object put(@RequestBody JDBCModel mode) { return this.support.save(mode); } @DeleteMapping public Object delete(@RequestParam Long id) { this.support.deleteById(id); return \"SUCCESS\"; }} 启动服务使用curl或者其他http客户端进行测试基本的增删改查功能 JDBC数据分页功能 由于JDBCSupport文件将继承的JpaRepository接口,而JpaRepository底层继承PagingAndSortingRepository接口,所以我们的接口会自动提供分页功能,只需要在查询的时候增加分页配置即可 修改JDBCController增加以下代码 12345@GetMapping(value = \"page\")public Object get(@RequestParam Integer page, @RequestParam Integer size) { return this.support.findAll(PageRequest.of(page, size));} 重启服务器测试分页功能 注意:由于jpa分页默认是从0开始,所以我们首页需要传递0 JDBC数据排序功能 在JPA中对查询数据排序和分页一样简单,我们只需要传递排序配置即可 修改JDBCController增加以下代码 1234@GetMapping(value = \"sort\")public Object sort() { return this.support.findAll(new Sort(Sort.Direction.DESC, \"id\"));} 需要注意的是sort中的排序字段是我们实体类中的字段,并不是数据库中的字段 JDBC数据排序分页组合功能 我们已经实现分页和排序功能,那么我们需要讲解一下如何做组合,代码也很简单,具体代码如下 修改JDBCController增加以下代码 123456@GetMapping(value = \"page_sort\")public Object sort(@RequestParam Integer page, @RequestParam Integer size) { Pageable pageable = PageRequest.of(page, size, new Sort(Sort.Direction.DESC, \"id\")); return this.support.findAll(pageable);} 代码中我们看到只需要在构建Pageable过程中传递Sort配置即可 自动创建SQL JPA提供自动创建SQL功能只需要在application.properties配置文件中加入以下配置 1spring.jpa.hibernate.ddl-auto=create 重启服务后,会自动创建数据表可用参数如下: validate 加载 Hibernate 时,验证创建数据库表结构 create 每次加载 Hibernate ,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。 create-drop 加载 Hibernate 时创建,退出是删除表结构 update 加载 Hibernate 自动更新数据库结构 如果你想保留表结构的数据,使用 update 即可 打印SQL日志 在调试程序中我们需要查看出现问题的sql,那么我们需要在application.properties配置文件中加入以下配置 1spring.jpa.show-sql=true 此时重启服务器.控制台会打印如下sql 12Hibernate: drop table if exists jdbcHibernate: create table jdbc (id bigint not null auto_increment, context varchar(64), name varchar(255), primary key (id)) engine=MyISAM 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-datajpa-jdbc-1.0.0.jar 源码地址 GitHub Gitee","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"DataJPA","slug":"Java/DataJPA","permalink":"https://learn-programming.edurt.io/categories/Java/DataJPA/"}],"tags":[{"name":"DataJPA","slug":"DataJPA","permalink":"https://learn-programming.edurt.io/tags/DataJPA/"},{"name":"JDBC","slug":"JDBC","permalink":"https://learn-programming.edurt.io/tags/JDBC/"}]},{"title":"整合ElasticSearch教程(基础版)","slug":"Java/DataJPA/datajpa-elasticsearch-basic","date":"2020-05-07T15:46:05.000Z","updated":"2020-10-09T10:35:01.295Z","comments":true,"path":"2020/05/07/Java/DataJPA/datajpa-elasticsearch-basic.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/07/Java/DataJPA/datajpa-elasticsearch-basic.html","excerpt":"","text":"本教程主要详细讲解Spring Data ElasticSearch,它向ElasticSearch提供Spring Data平台的抽象. ElasticSearch是基于文档的存储,以持久保存数据,并可用作数据库,缓存,消息代理等. 我们通过以下几个步骤进行讲解: 基础环境 创建项目 配置支持ElasticSearch 操作ElasticSearch数据 打包文件部署 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x DataJPA 2.x.x ElasticSearch 5.x.x 创建项目 初始化项目 1mvn archetype:generate -DgroupId=com.edurt.sli.slide -DartifactId=spring-learn-integration-datajpa-elasticsearch -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false 修改pom.xml增加elasticsearch的支持 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <parent> <artifactId>spring-learn-integration-datajpa</artifactId> <groupId>com.edurt.sli</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-learn-integration-datajpa-elasticsearch</artifactId> <name>Spring DataJPA ElasticSearch教程(基础版)</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${dependency.lombok.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version>${dependency.springboot2.common.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${dependency.springboot2.common.version}</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${plugin.maven.compiler.version}</version> <configuration> <source>${system.java.version}</source> <target>${system.java.version}</target> </configuration> </plugin> </plugins> </build></project> spring-boot-starter-data-elasticsearch整合ElasticSearch需要的依赖包 一个简单的应用类 1234567891011121314151617181920212223242526272829303132333435363738/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slide;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * <p> SpringBootDataJPAElasticSearchIntegration </p> * <p> Description : SpringBootDataJPAElasticSearchIntegration </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-07-25 10:24 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@SpringBootApplicationpublic class SpringBootDataJPAElasticSearchIntegration { public static void main(String[] args) { SpringApplication.run(SpringBootDataJPAElasticSearchIntegration.class, args); }} 配置支持ElasticSearch 在resources资源目录下创建一个application.properties的配置文件,内容如下 12spring.data.elasticsearch.cluster-name=esspring.data.elasticsearch.cluster-nodes=10.10.0.17:9300 操作ElasticSearch数据 在/src/main/java/com/edurt/sli/slide目录下创建model目录,并在该目录下新建ElasticSearchModel文件 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slide.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;import org.springframework.data.annotation.Id;import org.springframework.data.elasticsearch.annotations.Document;import org.springframework.data.elasticsearch.annotations.Field;import org.springframework.data.elasticsearch.annotations.FieldType;import java.nio.file.attribute.FileTime;/** * <p> ElasticSearchModel </p> * <p> Description : ElasticSearchModel </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-07-25 10:27 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Data@ToString@AllArgsConstructor@NoArgsConstructor@Document(indexName = \"test\", type = \"elasticsearch\", refreshInterval = \"1s\")public class ElasticSearchModel { @Id private Long id; private String title; @Field(type = FieldType.Auto, index = true, store = true) private String context;} @Document相当于Hibernate实体的@Entity/@Table(必写) 类型 属性名 默认值 描述 String indexName 无 索引库的名称,建议以项目的名称命名 String type “” 类型,建议以实体的名称命名 short shards 5 默认分区数 short replica 1 每个分区默认的备份数 String refreshInterval 1s 刷新间隔 String indexStoreType fs 索引文件存储类型 @Id相当于Hibernate实体的主键@Id注解(必写) @Field(相当于Hibernate实体的@Column注解),@Field默认是可以不加的,默认所有属性都会添加到ES中 类型 属性名 默认值 说明 FileType type FieldType.Auto 自动检测属性的类型 FileType index FieldIndex.analyzed 默认情况下分词 boolean store false 默认情况下不存储原文 String searchAnalyzer “” 指定字段搜索时使用的分词器 String indexAnalyzer “” 指定字段建立索引时指定的分词器 String[] ignoreFields {} 如果某个字段需要被忽略 在/src/main/java/com/edurt/sli/slide目录下创建repository目录,并在该目录下新建ElasticSearchSupport文件 12345678910111213141516171819202122232425262728293031323334/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slide.repository;import com.edurt.sli.slide.model.ElasticSearchModel;import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;import org.springframework.stereotype.Repository;/** * <p> ElasticSearchSupport </p> * <p> Description : ElasticSearchSupport </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-07-25 10:36 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@Repositorypublic interface ElasticSearchSupport extends ElasticsearchRepository<ElasticSearchModel, Long> {} 在ElasticsearchRepository中提供了一些基础的增删改查以及分页的功能. 测试增删改查的功能 在/src/main/java/com/edurt/sli/slide目录下创建controller目录,并在该目录下新建ElasticSearchController文件 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * \"License\"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edurt.sli.slide.controller;import com.edurt.sli.slide.model.ElasticSearchModel;import com.edurt.sli.slide.repository.ElasticSearchSupport;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;/** * <p> ElasticSearchController </p> * <p> Description : ElasticSearchController </p> * <p> Author : qianmoQ </p> * <p> Version : 1.0 </p> * <p> Create Time : 2019-07-25 10:39 </p> * <p> Author Email: <a href=\"mailTo:[email protected]\">qianmoQ</a> </p> */@RestController@RequestMapping(value = \"elasticsearch\")public class ElasticSearchController { @Autowired private ElasticSearchSupport support; @GetMapping public Object get() { return this.support.findAll(); } @PostMapping public Object post(@RequestBody ElasticSearchModel mode) { return this.support.save(mode); } @PutMapping public Object put(@RequestBody ElasticSearchModel mode) { return this.support.save(mode); } @DeleteMapping public Object delete(@RequestParam String id) { this.support.deleteById(Long.valueOf(id)); return \"SUCCESS\"; }} 添加数据 12shicheng@shichengdeMacBook-Pro ~> curl -X POST http://localhost:8080/elasticsearch -H 'Content-Type:application/json' -d '{\"title\": \"Hello ElasticSearch\", \"context\": \"我是SpringBoot整合ElasticSearch示例\"}'{\"id\":null,\"title\":\"Hello ElasticSearch\",\"context\":\"我是SpringBoot整合ElasticSearch示例\"}⏎ 修改数据 12shicheng@shichengdeMacBook-Pro ~> curl -X PUT http://localhost:8080/elasticsearch -H 'Content-Type:application/json' -d '{\"id\": 1,\"title\": \"Hello ElasticSearch\", \"context\": \"我是SpringBoot整合ElasticSearch示例,Modfiy\"}'{\"id\":1,\"title\":\"Hello ElasticSearch\",\"context\":\"我是SpringBoot整合ElasticSearch示例,Modfiy\"}⏎ 获取数据 12shicheng@shichengdeMacBook-Pro ~> curl -X GET http://localhost:8080/elasticsearch{\"content\":[{\"id\":null,\"title\":\"Hello ElasticSearch\",\"context\":\"我是SpringBoot整合ElasticSearch示例,Modfiy\"},{\"id\":1,\"title\":\"Hello ElasticSearch\",\"context\":\"我是SpringBoot整合ElasticSearch示例,Modfiy\"}],\"pageable\":{\"sort\":{\"sorted\":false,\"unsorted\":true},\"offset\":0,\"pageSize\":2,\"pageNumber\":0,\"paged\":true,\"unpaged\":false},\"facets\":[],\"aggregations\":null,\"scrollId\":null,\"totalElements\":2,\"totalPages\":1,\"size\":2,\"number\":0,\"numberOfElements\":2,\"first\":true,\"sort\":{\"sorted\":false,\"unsorted\":true},\"last\":true}⏎ 删除数据 12shicheng@shichengdeMacBook-Pro ~> curl -X DELETE 'http://localhost:8080/elasticsearch?id=1'SUCCESS⏎ 打包文件部署 打包数据 1mvn clean package -Dmaven.test.skip=true -X 运行打包后的文件即可 1java -jar target/spring-learn-integration-datajpa-elasticsearch-1.0.0.jar 源码地址 GitHub Gitee","categories":[{"name":"Java","slug":"Java","permalink":"https://learn-programming.edurt.io/categories/Java/"},{"name":"DataJPA","slug":"Java/DataJPA","permalink":"https://learn-programming.edurt.io/categories/Java/DataJPA/"}],"tags":[{"name":"DataJPA","slug":"DataJPA","permalink":"https://learn-programming.edurt.io/tags/DataJPA/"},{"name":"ElasticSearch","slug":"ElasticSearch","permalink":"https://learn-programming.edurt.io/tags/ElasticSearch/"}]},{"title":"示例","slug":"example/index","date":"2020-05-07T13:00:58.000Z","updated":"2020-05-08T02:40:39.787Z","comments":true,"path":"2020/05/07/example/index.html","link":"","permalink":"https://learn-programming.edurt.io/2020/05/07/example/index.html","excerpt":"","text":"这是示例文章…","categories":[{"name":"example","slug":"example","permalink":"https://learn-programming.edurt.io/categories/example/"}],"tags":[{"name":"示例","slug":"示例","permalink":"https://learn-programming.edurt.io/tags/%E7%A4%BA%E4%BE%8B/"}]}]}