首页
友链
关于
免责声明
Search
1
王者营地战绩数据王者荣耀查询网页源码
6,210 阅读
2
群晖Active Backup for Business套件备份Linux服务器教程
4,384 阅读
3
影视分享
4,313 阅读
4
(亲测)Jrebel激活破解方式2019-08-21
4,289 阅读
5
centos7 安装及卸载 jekenis
3,573 阅读
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
登录
Search
标签搜索
docker
springboot
Spring Boot
java
linux
Shiro
Graphics2D
图片
游戏账号交易
Mybatis
Spring Cloud
centos
脚本
Web Station
群辉
王者营地
战绩查询
平台对接
Spring Cloud Alibaba
nacos
绿林寻猫
累计撰写
249
篇文章
累计收到
26
条评论
首页
栏目
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
页面
友链
关于
免责声明
搜索到
195
篇与
后端
的结果
2021-12-08
Spring Boot 简介
前言Spring Team在现有Spring框架的基础上发布了一个创新的框架:Spring Boot。Spring Boot的开发团队是:PivotalSpring Boot的主要作用是:简化开发,减少配置(简化配置和部署spring应用程序的过程)Spring Boot框架提倡:一键部署、习惯优于配置Spring Boot还是一个微框架,它与目前流行的微服务紧密联系,可以开发微应用。1.Spring Boot主要特点 创建独立的Spring应用程序 嵌入的Tomcat,无需部署WAR文件 简化Maven配置 自动配置Spring 提供生产就绪型功能,如指标,健康检查和外部配置 绝对没有代码生成和对XML没有要求配置 2.新项目为什么需要Spring Boot 简化基于Java的应用程序开发,单元测试和集成测试过程。 通过提供一些默认值来减少开发,单元测试和集成测试时间。 提高生产力。 当使用默认值时,Spring Boot有自己的看法。如果不指定详细信息,它将使用其自己的默认配置。如果想要持久化,但是没有在POM文件中指定任何东西,那么Spring Boot会将Hibernate带有HSQLDB数据库的配置作为JPA提供者。 为大型项目(例如嵌入式服务器,安全性,度量,健康检查,外部化配置)提供许多非常常见的非功能特性/解决方案。 3.pring Boot精要 自动配置:针对很多Spring应用程序常见的应用功能,Spring Boot能自动提供相关配置 起步依赖:告诉Spring Boot需要什么功能,它就能引入需要的库。 命令行界面:这是Spring Boot的可选特性,借此你只需写代码就能完成完整的应用程序,无需传统项目构建。 Actuator:让你能够深入运行中的Spring Boot应用程序,一探究竟。 4.Spring Boot的核心与限制 Spring Boot的核心还是Spring。 未来的Spring项目不会有任何XML配置作为它的一部分,一切都将由项目Spring Boot处理。 5.环境搭建(IDEA) IntelliJ IDEA 14.1已经支持Spring Boot。5.1【File】-【New】-【Project】然后选择【Spring Initializr】 注:如果有报错,重试几次,可能是网络问题引起。5.2选择JDK,根据图进行操作:注:这里可以选择用war包,即以后将war包复制到Tomcat下解压部署即可。5.3在初始依赖的导入时勾选要导入的包,比如Web、MySQL等,可以只选择支持Web,其它的都在pom.xml中导入依赖。注意:导入两个依赖,Spring Boot会自动找到与之相应的包,一并加载(整体打包依赖)。 接下来填写项目名及项目源代码保存路径,如下:填好后点Finish,现在已经初始化了一个Spring Boot框架。 项目结构注意:在这里要将java文件夹设置为:Sources Root;将test文件夹设置为:Test Sources Root访问静态资源:Spring Boot将静态资源放在了src/main/resources/static中。如:放入一张图片,启动Spring Boot,通过浏览器打开看。注:resources中的static和templates文件夹是受保护的,必须要有访问权限。templates:存放模板页,如thymeleaf,freemarker……。前后端分离:通过前端技术去调用,不使用任何后台相关技术,如freemarker、velocity、jsp等。注:前后端分离一般在并发量比较高的情况下使用。大型项目(互联网)前端调用全部是由前端团队去开发,后台只需要写好接口就可以了,告诉前端如何调用参数即可。前端:前端设计,前端开发+PHP(调用后端接口,获取数据绑定)后端:后端开发 pom.xml Maven构建说明文件。WaterApplication 一个带有main方法的类,用于启动应用程序(关键)。WaterApplicationTests 一个空的Junit测试类。application.properties 一个空的properties文件,可以根据需要添加配置属性。 Spring Boot依赖使用Spring Initializr创建Spring Boot项目,pom.xm中自带依赖包。同时Spring Boot会自动找到与之相应的包,一并加载(整体打包依赖)。<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <!--Spring Boot的父依赖,下面的依赖都继承该依赖。(可省略version版本)--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <!--spring-boot-starter-web包含:Spring-WebMVC、Spring-Web、Jackson、validation、Tomcat、Starter等内容--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--连接MySQL数据库,导入C3P0依赖--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> </dependencies> <!--打包。executable jars 又称 fat jars,是可以直接在生产环境中运行的,包含所有编译生成的class文件以及依赖包。 注意,Spring Boot的这种打包方式需要使用Spring Boot提供的 spring-boot-maven-plugin 。--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> 创建项目包(1)在创建Spring Boot项目时,会默认创建包和类,比如: 目录名 说明 Templates 模板文件(Freemarker、template、thymeleaf等 ),受保护的,必须要有权限才能访问(需认证通过)。 Static 静态资源文件(图片、JS、css等),受保护的,必须要有权限才能访问(需认证通过)。 Webapp 普通前端页面文件,不受保护,Spring Boot中不推荐JSP,所在webapp中放JSP已过时。 注:Mvnw及mvnw.cmd文件没啥用,可以删除。(Eclipse)(2)打开Demo1Application.java文件查看源代码: @SpringBootApplicationpublic class Demo1Application { public static void main(String[] args) { SpringApplication.run(Demo1Application.class, args);}} 启动Spring Boot内置集成了Tomcat,所以无需启动Tomcat即可执行Demo1Application.java中的main方法。空启动后控制面板会出现如下图片:出现该界面,使用浏览器访问http://127.0.0.1:8080出现无法访问,请删除pom.xml 中Tomcat作用域代码: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope></dependency> 删除后重新启动,并访问http://127.0.0.1:8080测试在com.zking.demo1中创建包:controller包,并创建TestController.java// @RestController是Controller和ResponseBody合并的,用这个,下面的@ResponseBody可省略,新版本中出现的 @Controller public class TestController{ @ResponseBody //做为ajax返回 @RequestMapping(“/test”) public String say(){ Return “Spring Boot 你大爷”; } } 热部署当我们修改文件和创建文件时,都需要重新启动项目。这样频繁的操作很浪费时间,配置热部署可以让项目自动加载变化的文件,省去的手动操作。在 pom.xml 文件中添加如下配置:<!-- 热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>true</scope> </dependency><build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- 没有该配置,devtools 不生效 --> <fork>true</fork> </configuration> </plugin> </plugins> </build>多环境切换application.properties 是 springboot 在运行中所需要的配置信息。当我们在开发阶段,使用自己的机器开发,测试的时候需要用的测试服务器测试,上线时使用正式环境的服务器。这三种环境需要的配置信息都不一样,当我们切换环境运行项目时,需要手动的修改多出配置信息,非常容易出错。为了解决上述问题,springboot 提供多环境配置的机制,让开发者非常容易的根据需求而切换不同的配置环境。在 src/main/resources 目录下创建三个配置文件:application-dev.properties:用于开发环境application-test.properties:用于测试环境application-prod.properties:用于生产环境我们可以在这个三个配置文件中设置不同的信息,application.properties 配置公共的信息。在 application.properties 中配置:spring.profiles.active=dev注解介绍下面列出 Spring Boot 开发中常用的注解:@Configuration # 作用于类上,相当于一个 xml 配置文件 @Bean # 作用于方法上,相当于 xml 配置中的 <bean> @SpringBootApplication # Spring Boot的核心注解,是一个组合注解,用于启动类上 @EnableAutoConfiguration # 启用自动配置,允许加载第三方 Jar 包的配置 @ComponentScan # 默认扫描 @SpringBootApplication 所在类的同级目录以及它的子目录 @PropertySource # 加载 properties 文件 @Value # 将配置文件的属性注入到 Bean 中特定的成员变量 @EnableConfigurationProperties # 开启一个特性,让配置文件的属性可以注入到 Bean 中,与 @ConfigurationProperties 结合使用 @ConfigurationProperties # 关联配置文件中的属性到 Bean 中 @Import # 加载指定 Class 文件,其生命周期被 Spring 管理 @ImportResource # 加载 xml 文件
2021年12月08日
236 阅读
0 评论
0 点赞
2021-12-08
Spring Cloud 入门 之 Ribbon (二)
一、前言本篇文章将介绍如何使用 Ribbon 完成发现服务的调用以及其负载均衡的规则的使用。二、简单介绍Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端负载均衡工具,其主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。其运行原理如下图:Ribbon 运行时分成 2 个步骤:先选择在同一个区域负载较少的 EurekaServer; 再根据用户指定的策略,在从 EurekaServer 中获取注册列表中的服务信息进行调用。 其中,Ribbon 提供多种负载均衡策略:如轮询、随机、响应时间加权等。三、实战演练我们在 user-web 项目的基础上进行修改。不清楚的读者请先转移至 Sprng Cloud入门之Eureka(一)进行浏览。此外,额外的创建 2 个 user-provider (原user-api)项目,即现在有 3 个 user-provider 项目给 user-consumer (原user-web)进行消费。以下为user-consumer (原user-web):3.1添加依赖 <!--ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.1.0.RELEASE</version> </dependency>3.2修改请求类@Configuration public class RestConfiguration { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } // @Bean // public IRule testRule() { // return new RandomRule(); // } }Ribbon 是客户端负载均衡工具,所以在 getRestTemplate 方法上添加 @LoadBalanced 注解实现负载均衡。3.2修改请求地址@RestController @RequestMapping("/user") public class UserController { @Autowired private RestTemplate restTemplate; // @RequestMapping("get/{id}") // public User get(@PathVariable("id") Integer id) throws Exception { // // 没有使用 Eureka 时,uri 为消息提供者的地址,需要指定 ip 和 端口 // return restTemplate.getForObject(new URI("http://localhost:8081/provider/user/get/" + id), User.class); // } // @Autowired // private DiscoveryClient client; // // @RequestMapping("get/{id}") // public User get(@PathVariable("id") Integer id) throws Exception { // // List<ServiceInstance> list = this.client.getInstances("USER-API"); // String uri = ""; // for (ServiceInstance instance : list) { // if (instance.getUri() != null && !"".equals(instance.getUri().toString())) { // uri = instance.getUri().toString(); // break; // } // } // return restTemplate.getForObject(uri + "/provider/user/get/" + id, User.class); // } @RequestMapping("get/{id}") public User get(@PathVariable("id") Integer id) throws Exception { // 使用 Eureka + Ribbon 后,uri 填写服务名称即可 return restTemplate.getForObject("http://USER-API/provider/user/get/" + id, User.class); } }修改 DiscoveryClient 相关代码,使用 USER-API 服务名称作为请求 URL。3.3在启动类上将 @EnableDiscoveryClient 替换成 @EnableEurekaClient 注解。4.测试依次启动 eureka-server 、 user-provider、 user-provider-8082 、 user-provider-8083 、user-consumer项目源码:https://github.com/Uncle-LiuY/ribbon-test 以上是参考其他文章而写的,不足之处请指出,谢谢。
2021年12月08日
210 阅读
0 评论
0 点赞
2021-12-08
Spring Cloud RestTemplate报错:java.lang.IllegalStateException: No instances available for
java.lang.IllegalStateException: No instances available for localhost 原:restTemplate.getForObject( uri+"/user/getname",User.class); //uri为得到的地址 如:http://127.0.0.1改:rrestTemplate.getForObject( "http://user-api/user/getname",User.class);//改为在eureka上注册的application.name restTemplate访问https,这个暂时没有去测试,希望对大家有用https://cloud.tencent.com/developer/article/1339988
2021年12月08日
185 阅读
0 评论
0 点赞
2021-12-08
Spring boot 整合之拦截器
1.创建config包,再在下面创建intercepors包及LoginInterceptor类@Component public class LoginInterceptor implements HandlerInterceptor { private Logger logger = LoggerFactory.getLogger(LoginInterceptor.class); //这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //每一个项目对于登陆的实现逻辑都有所区别,我这里使用最简单的Session提取User来验证登陆。 HttpSession session = request.getSession(); //这里的User是登陆时放入session的 User user = (User) session.getAttribute("user"); //如果session中没有user,表示没登陆 if (user == null){ //这个方法返回false表示忽略当前请求,如果一个用户调用了需要登陆才能使用的接口,如果他没有登陆这里会直接忽略掉 //当然你可以利用response给用户返回一些提示信息,告诉他没登陆 //跳转到登录界面 logger.info("跳转至登录"); response.sendRedirect(request.getContextPath()+"/login"); return false; }else { return true; //如果session里有user,表示该用户已经登陆,放行,用户即可继续调用自己需要的接口 } } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }2.在config包下创建WebConfigurer类@Configuration public class WebConfigurer implements WebMvcConfigurer { @Autowired private LoginInterceptor loginInterceptor; // 这个方法是用来配置静态资源的,比如html,js,css,等等 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { } // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效 @Override public void addInterceptors(InterceptorRegistry registry) { // addPathPatterns("/**") 表示拦截所有的请求, // excludePathPatterns("/login", "/register","/*.js","/*.css") 表示除了登陆与注册、js、css之外,因为登陆、注册、js、css不需要登陆也可以访问 registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/register","/*.js","/*.css"); } }
2021年12月08日
169 阅读
0 评论
0 点赞
2021-12-08
Spring Boot 使用WebSocket(一)
依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> 创建服务器端点:对于 WebSocket 的使用,可以先通过 Spring 创建 Java 配置文件。在这个文件 中, 先新建 ServerEndpointExporter 对象 , 通过它可以定义 WebSocket 服务器的端点 , 这样客户端就能请求服务器 的端点,其内容如代码清单,有了这个 Bean ,就可以使用@ServerEndpoint 定义一个端点服务类。在这个站点服务类中,还可以定义 WebSocket 的打开 、关闭 、错误和发送消息的方法。package com.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } } 创建webSocket:WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller直接@ServerEndpoint("/websocket")@Component启用即可,然后在里面实现@OnOpen,@onClose,@onMessage, @OnError等方法package com.demo.config; import org.springframework.stereotype.Service; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; @ServerEndpoint("/ws/{sid}") @Service public class WebSocket { /** * 这里稍微解释一下这些主要注解的作用 。 * • @ServerEndpoint("/ws") : * 表示让 Spring 创建 WebSocket 的服务端点 ,其中请求地址是“/ws”。 * • @OnOpen: * 标注客户端打开 WebSocket 服务端点调用方法。 * • @OnClose : * 标注客户端关 闭 WebSocket 服务端点调用方法。 * • @OnMessage : * 标注客户端发送消息, WebSocket 服务端点调用方法。 * • @OnError: * 标注客户 端请求 WebSocket 服务端点发生异常调用 方法。 * 因为每一个客户端打开时,都会为其创建一个 WebSocket 对象,所以这里的打开方 * 法中都会去计数并且将这个对象保存到 CopyOnWriteArraySet 中,这样就可以知道拥有多少连接。对 * 于关 闭方法则是清除这个对象,并且计数减一。对于消息发送方法 ,则是通过轮询对所有的客户端 * 连接都给予发送消息,所以所有的连接都可以收到这个消息。但是有时候可能只 是需要发送给特定13.4 WebSocket 应用 309 * 的用户,则需要得到用户的信息,然后再发送给特定的用户 。 */ /**静态变量,用来记录当前在线连接数 。 应该把它设计成线程安全的*/ private static int onlineConunt = 0; /**连接标识编号*/ private String sid=""; /**oncurrent 包的线程安全 Set ,用来存放每个客户端对应的 WebSocketServiceimpl 对象*/ private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>(); /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/ private Session session; /** 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam("sid")String sid ){ this.sid=sid; this.session = session; //加入 set 中 webSocketSet.add(this); //在线数加1 addOnlineCount(); System.out.println("有新连接加入!"+sid+"当前在线人数为:"+getOnlineConunt()); try { sendMessage("有新的连接加入了!!"); } catch (IOException e) { System.out.println("IO异常"); } } //连接关闭调用的方法 @OnClose public void onClose(){ //从set中删除 webSocketSet.remove(this); //在线数减1 subOnlineCount(); System.out.println("有一连接关闭!当前在线人数为:"+getOnlineConunt()); } /** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 * @param session */ @OnMessage public void onMessage(String message,Session session){ System.out.println("来自客户端的消息:"+message); //群发消息 for(WebSocket item : webSocketSet){ //获取当前用户名称 try { item.sendMessage(message); } catch (IOException e) { System.out.println("发送消息异常"); } } } //发送错误时调用 @OnError public void onError(Session session,Throwable error){ System.out.println("发送错误"); error.printStackTrace(); } /** * 根据编号给指定客户端发送消息 * @param message 客户端消息 * @throws IOException */ public static void appointMessage(String message,String sid) throws IOException { for(WebSocket item : webSocketSet){ if(item.getSid().equals(sid)){ item.sendMessage(message); } } } /** * 发送消息 * @param message 客户端消息 * @throws IOException */ private void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } //返回在线数 private static synchronized int getOnlineConunt() { return onlineConunt; } //当连接人数增加时 private static synchronized void addOnlineCount() { WebSocket.onlineConunt ++; } //当连接人数减少时 private static synchronized void subOnlineCount() { WebSocket.onlineConunt --; } public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } } 前端界面:<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script type="text/javascript"> var ws = null; if('WebSocket' in window){ alert("你的浏览器支持 WebSocket"); ws = new WebSocket("ws://192.168.0.142:8080/ws/123"); } else { alert('你的浏览器不支持webSocket'); } //建立成功建立的回调方法 ws.onopen = function(event){ alert("消息已发送") appendMessage("open"); } //接收到消息的回调方法 ws.onmessage = function(event){ alert("接收到服务端发的消息") appendMessage(event.data); } //连接关闭的回调方法 ws.onclose = function(){ alert("连接已关闭") appendMessage("close"); } //连接发送错误的回调方法 ws.onerror = function(){ alert("连接发送错误") appendMessage("error"); } //监听窗口关闭事件,当窗口关闭时,主动关闭webSocket连接 //防止连接还没断开就关闭窗口,server端会抛异常 ws.onbeforeunload = function(){ alert("窗口关闭了,关闭socket连接") ws.onclose(); } //将消息显示在网页上 function appendMessage(message){ var context = $("#context").html() +"<br/>" +message; $("#context").html(context); } //关闭连接 function closeWebSocket(){ ws.close(); } //发送消息 function sendMessage(){ var message = $("#message").val(); ws.send(message); } </script> </head> <body> <input id="message" type="text"/> <button onclick="sendMessage()" >发送消息</button> <button onclick="closeWebSocket()" >关闭连接</button> <div id="context"></div> </body> </html>
2021年12月08日
219 阅读
0 评论
0 点赞
2021-12-08
Spring Cloud 入门 之 Feign(三)
一、前言在上一篇文章Spring Cloud 入门 之 Ribbon (二) 中介绍了 Ribbon 使用负载均衡调用微服务,但存在一个问题:消费端每个请求方法中都需要拼接请求服务的 URL 地址,存在硬编码问题且不符合面向对象编程思想。如果服务名称发生变化,消费端也需要跟着修改。本篇文章将介绍 Feign 来解决上边的问题。二、简单介绍Feign 是一个声明式的 Web Service 客户端。使用 Feign 能让编写 Web Service 客户端更加简单,同时支持与Eureka、Ribbon 组合使用以支持负载均衡。Spring Cloud 对 Feign 进行了封装,使其支持了 Spring MVC 标准注解和 HttpMessageConverters。Feign 的使用方法是定义一个接口,然后在其上边添加 @FeignClient 注解。三、实战演练本次测试案例基于之前发表的文章中介绍的案例进行演示,不清楚的读者请先转移至 Spring Cloud 入门 之 Ribbon (二) 进行浏览。3.1添加依赖在user-consumer和user-provider都添加(注意版本冲突) <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1.0.RELEASE</version> </dependency>3.2 定义新接口在 user-consumer 项目中新建一个接口@FeignClient(value = "user-api") public interface UserClient { @RequestMapping(value = "/provider/user/get/{id}") User get(@PathVariable("id") Integer id); }使用 @FeignClient 注解指定调用的微服务名称,封装了调用 USER-API 的过程,作为消费方调用模板。注意:Feign 接口的定义最好与对外开发的 controller 中的方法定义一致,此处的定义与 user-provider 项目中 controller 类定义的方法一致。在 user-consumer 项目中直接使用UserClient调用@Service public class UserServiceImpl implements IUserService { @Autowired private UserClient userClient; @Override public User get(User user) { return userClient.get(user.getId()); } }3.3 启动 Feign 功能在启动类上添加 @EnableEeignClients 注解:@EnableFeignClients(basePackages = {"com.test"}) @EnableEurekaClient @SpringBootApplication public class OrderServerApplication { public static void main(String[] args) { SpringApplication.run(OrderServerApplication.class, args); } }依次启动 eureka-server 、 user-provider、 user-provider-8082 、 user-provider-8083 、user-consumer
2021年12月08日
222 阅读
0 评论
0 点赞
2021-12-08
SpringCloud Feign报错 Caused by: java.lang.IllegalStateException: Method has too many Body parameters
Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract com.hujiang.framework.web.domain.AjaxResult com.hujiang.project.zhgd.client.SystemClient.getSystemPrivileges_app(java.lang.Integer,java.lang.Integer)GET方式错误写法@RequestMapping(value="/test", method=RequestMethod.GET) User test(String name, int age); 启动服务的时候,会报如下异常:Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract com.hujiang.framework.web.domain.AjaxResult com.hujiang.project.zhgd.client.SystemClient.getSystemPrivileges_app(java.lang.Integer,java.lang.Integer)异常原因:当使用Feign时,如果发送的是get请求,那么需要在请求参数前加上@RequestParam注解修饰,Controller里面可以不加该注解修饰。正确写法@RequestMapping(value="/test", method=RequestMethod.GET) User test(@RequestParam("name") String name,@RequestParam("age") int age); POST方式 错误写法public int save(@RequestBody Person p, @RequestBody UserModel user);feign中你可以有多个@RequestParam,但只能有不超过一个@RequestBody。正确写法public int save(@RequestBody Person p,@RequestParam("userId") String userId,@RequestParam("userTel") String userTel);
2021年12月08日
353 阅读
0 评论
0 点赞
2021-12-08
Spring Cloud RestTemplate 单文件上传、多文件上传
单文件上传:服务提供者controller @RequestMapping(value = "/addProject",method = RequestMethod.POST) public AjaxResult addSave( HjProject hjProject, MultipartFile file)throws Exception { if (file != null&&!file.isEmpty()) { //上传图片到oss服务器 String url = AliyunOSSClientUtil.uploadFileImg(file, "file", hjProject.getShortName() + System.currentTimeMillis() + ".jpg"); hjProject.setProjectImage(url.substring(0,url.indexOf("?"))); } int i = hjProjectService.insertHjProject(hjProject); if(i>0){ HjCompanyProject hjCompanyProject = new HjCompanyProject(); hjCompanyProject.setCompanyId(cid); hjCompanyProject.setProjectId(hjProject.getId()); return toAjax(hjCompanyProjectService.insertHjCompanyProject(hjCompanyProject)); } return toAjax(i); }消费者RestTemplate@Configuration public class RestConfiguration { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }controller @Autowired private RestTemplate restTemplate; @RequestMapping("/addProject") public AjaxResult addSave(HjProject hjProject, MultipartFile file)throws Exception { //设置请求头 HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("multipart/form-data"); headers.setContentType(type); //生成临时文件 File localFile = new File(getPath(),"/"+file.getOriginalFilename()); file.transferTo(localFile); FileSystemResource resource = new FileSystemResource(localFile); MultiValueMap<String, Object> param = new LinkedMultiValueMap<>(); param.add("file", resource);//文件 for (Field f : hjProject.getClass().getDeclaredFields()) { f.setAccessible(true); //遍历对象属性:值 param.add(f.getName(), f.get(hjProject)); } //用HttpEntity封装整个请求报文 HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(param, headers); //请求服务 AjaxResult s = restTemplate.postForObject("http://服务名称/provider/project/addProject", files, AjaxResult.class); System.out.println(s); //删除临时文件 localFile.delete(); return s; } 多文件上传:服务消费者controllerpublic AjaxResult upload(MultipartFile[] file)throws Exception{ MultiValueMap<String, Object> param = new LinkedMultiValueMap<>(); //设置请求头 HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("multipart/form-data"); headers.setContentType(type); File[] files = new File[file.length]; //遍历文件数组 for(int i=0;i<file.length;i++){ File localFile = new File(Util.getPath(),"/"+file[i].getOriginalFilename()); file[i].transferTo(localFile); files[i]=localFile; //多个MultipartFile同时添加进 MultiValueMap key为file //MultiValueMap可以让一个key对应多个value param.add("file", new FileSystemResource(localFile)); } //用HttpEntity封装整个请求报文 HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(param, headers); AjaxResult reult = restTemplate.postForObject("http://服务名称/provider/fileApi/upload", httpEntity, AjaxResult.class); //删除临时文件 for(int i=0;i<files.length;i++){ if(files[i].exists()){ System.out.println("删除临时文件"+files[i].getName()); files[i].delete(); } } return reult; }
2021年12月08日
91 阅读
0 评论
0 点赞
2021-12-08
springcloud服务配置公网ip
eureka 配置eureka: instance: instance-id: aaa #服务示例名 ip-address: 123.123.123.123 #公网ip
2021年12月08日
124 阅读
0 评论
0 点赞
2021-12-08
Spring boot集成Swagger
1.配置pom.xml <!-- swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <!-- swagger-ui --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version>2.启动类import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = "com") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }3.配置configpackage com.example.demo.config; import io.swagger.annotations.ApiOperation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket swaggerSpringMvcPlugin() { return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).build(); } } 4.配置controllerpackage com.example.demo.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @Api(description = "测试接口") @RestController @RequestMapping(value = "/index",method = RequestMethod.POST) public class IndexController { @ApiOperation(value = "测试") @PostMapping("/test") public String index(){ return "00000"; } } 启动项目访问:http://localhost:8080/swagger-ui.html 作用范围 API 使用位置对象属性 @ApiModelProperty 用在参数对象的字段上协议集描述 @Api 用在Conntroller类上协议描述 @ApiOperation 用在controller方法上Response集 @ApiResponses 用在controller方法上Response @ApiResponse 用在@ApiResponses里面非对象参数集 @ApilmplicitParams 用在controller方法上 非对象参数描述 @ApiImplicitParam 用在@ApiImplicitParams的方法里边 描述返回对象的意义 @ApiModel 用在返回对象类上 paramType:表示参数放在哪个地方 header-->请求参数的获取:@RequestHeader(代码中接收注解) query-->请求参数的获取:@RequestParam(代码中接收注解) path(用于restful接口)-->请求参数的获取:@PathVariable(代码中接收注解) body-->请求参数的获取:@RequestBody(代码中接收注解) form(不常用)若出现404: import org.springframework.stereotype.Component; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Component public class WebMvcConfig implements WebMvcConfigurer { /** * 添加静态资源文件,外部可以直接访问地址 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } }
2021年12月08日
140 阅读
0 评论
0 点赞
1
...
17
18
19
20