jsp调用controller方法_RPC调用_服务注册与发现

RPC调用_单体架构_SOA架构

系统架构的演变

1 传统的单体架构

1.1 什么是单体架构

一个归档包(例如 war 格式或者 Jar 格式)包含了应用所有功能的应用程序,我们通常称之 为单体应用。也称之为单体应用架构,这是一种比较传统的架构风格。

903ff23387c60e38c181b03fa37645af.png

1.2 单体架构优点

便于开发:只需借助 IDE 的开发,调试功能即可完成 易于测试:只需要通过单元测试或浏览器即可完成测试 易于部署:打包成单一可执行 jar 或者 war 包,完成 jar 或者 war 部署即可

1.3 单体架构缺点

复杂性高:整个项目包含的模块非常多,模块的边界模糊,依赖关系不清晰,代码质量参差 不齐,整个项目非常复杂,修改一个 BUG 都会造成隐含的缺陷。

部署速度逐渐变慢:随着代码的增加,构建和部署的时间也会增加。而在单体应用中,每次 功能的变更或缺陷的修复都会导致我们需要重新部署整个应用。

扩展能力受限:单体应用只能作为一个整体进行扩展,无法结合业务模块的特点进行伸缩。

阻碍技术创新: 单体应用往往使用统一的技术平台或方案解决所有问题,团队的每个成员都 必须使用相同的开发语言和架构,想要引入新的框架或技术平台非常困难。

2SOA 架构(重点理解)

2.1 什么是 SOA 架构

SOA 是 Service-Oriented Architecture 的英文缩写,就是面向服务的架构。这里的服务可以理 解为 service 层业务服务。将系统拆分为不同的服务单元,通过网络协议服务单元之间进行 通信。服务单元完成一个特定功能(如:验证、支付、登录等等),通过服务单元之间的集成 组成完整的应用程序。

SOA 架构中由两个重要的角色:

服务提供者(Provider)和服务使用者(Consumer)

ec8f55656fb66b2669a0f08b09f659e9.png

2.2SOA 架构的优点

更易维护:业务服务提供者和业务服务使用者的松散耦合关系。当需求发生变化的时候,不 需要修改提供业务服务的接口,只需要调整业务服务流程或者修改操作即可,整个应用系统 也更容易被维护。

更高的可用性:该特点是在于服务提供者和服务使用者的松散耦合关系上得以发挥与体现。 使用者无须了解提供者的具休实现细节。

更好的伸缩性:依靠业务服务设计、开发和部署等所采用的架构模型实现伸缩性。使得服务 提供者可以互相彼此独立地进行调整,以满足新的服务需求。

2.3SOA 架构的缺点

减低了系统的性能

系统之间交互需要使用远程通信,接口开发增加工作量

3 什么是 RPC 调用

RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求 服务,而不需要了解底层网络技术的协议。请求程序就是一个客户机,而服务提供程序就是 一个服务器

841aabebe3f5c0baf97b25a9fa506b57.png

4 RPC 的应用场景

支付宝、微信、银联等第三方支付接入

bcc8cff561c58e5ad43846ec9bdba859.png

公司内部的不同业务系统,不同技术平台的整合

cbed26bf3ce0a5f121ff8c9c2f1d24c9.png

5 RPC 的实现方式

RMI:Java 提供的基于 java 平台 RPC 远程调用技术,服务消费者和服务提供者是 java 平台

16c5c8e331ab99ee273f91d818ff6069.png

WEBSERVICE:通过 Http 协议,请求发送 xml 和响应 xml 的 RPC 远程调用技术,最大的特征使用 xml 进行数据交互,可以实现跨平台调用。

f45fad3f6df1eec12982b644bc3a2646.png

HttpClient:Http 客户端工具,Java 程序通过 HttpClient 发送 Http 协议的请求,直接获得远程 资源

54a09461169f76cbdb6e49dbbf17927c.png

1d155b7e237e359a6e81aee60323cb23.png

HttpClient 实现 RPC 调用

1、HttpClient 介绍 HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程 序需要直接通过 HTTP 协议来访问网络资源。 HttpClient 是 Apache Jakarta Common 下的子项目,供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)支持 RestFul。

2、服务提供者实现

2.1 业务需求说明

实现:通过用户系统访问订单系统,获得某个用户的订单信息。

ae67dbe744b60ccb1ba129cc34c7ae8d.png

2.2 创建 order-sys 项目

<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"><modelVersion>4.0.0</modelVersion><groupId>com.bjsxt.provider</groupId><artifactId>order-sys</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><properties><!-- spring 依赖 --><spring.version>4.3.18.RELEASE</spring.version><jstl.version>1.2</jstl.version><servlet-api.version>2.5</servlet-api.version><jsp-api.version>2.0</jsp-api.version><jackson.version>2.9.0</jackson.version></properties><dependencies><!-- jsp相关依赖 --><!-- servlet依赖 --><!-- jstl依赖 --><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>${jstl.version}</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>${servlet-api.version}</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jsp-api</artifactId><version>${jsp-api.version}</version><scope>provided</scope></dependency><!-- springmvc依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency></dependencies><build><finalName>order</finalName><plugins><!-- 配置Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version><configuration><path>/order</path><port>7070</port></configuration></plugin></plugins></build>
</project>

2.3 创建 Order 订单实体类

package com.bjsxt.domain;/**** 订单的实体类* @author Administrator**/
public class Order {private String id;private Double total;private String date;public String getId() {return id;}public void setId(String id) {this.id = id;}public Double getTotal() {return total;}public void setTotal(Double total) {this.total = total;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}}

3.4 创建 OrderController

package com.bjsxt.controller;import java.util.ArrayList;
import java.util.List;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import com.bjsxt.domain.Order;@Controller
public class OrderController {/*** 接收http请求,响应订单集合* **/@RequestMapping("/loadOrderList")public String loadOrderList(String uid,Model model){Order o1=new Order();o1.setId("111");o1.setTotal(123.0);o1.setDate("2018-10-10");Order o2=new Order();o2.setId("222");o2.setTotal(1232.0);o2.setDate("2018-10-13");Order o3=new Order();o3.setId("333");o3.setTotal(333.0);o3.setDate("2018-10-31");List<Order> list = new ArrayList<>();list.add(o1);list.add(o2);list.add(o3);model.addAttribute("list", list);return "index.jsp";}/*** 接收http请求,响应订单集合,完成的是异步响应* 将List集合序列化为json串响应* **/@RequestMapping("/loadOrderList02")@ResponseBodypublic List<Order> loadOrderList02(String uid){System.out.println("uid="+uid);Order o1=new Order();o1.setId("111");o1.setTotal(123.0);o1.setDate("2018-10-10");Order o2=new Order();o2.setId("222");o2.setTotal(1232.0);o2.setDate("2018-10-13");Order o3=new Order();o3.setId("333");o3.setTotal(333.0);o3.setDate("2018-10-31");List<Order> list = new ArrayList<>();list.add(o1);list.add(o2);list.add(o3);return list;}
}

2.5 配置 springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>-<beans xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans"><!-- 扫描controller --><context:component-scan base-package="com.bjsxt.controller"/><mvc:annotation-driven/></beans>

2.6 配置 web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"><display-name>order</display-name><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list><servlet-mapping><servlet-name>default</servlet-name><url-pattern>/favicon.ico</url-pattern></servlet-mapping><!-- 以监听器的方式启动spring容器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 指定spring的配置文件 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext-*.xml</param-value></context-param><!-- POST请求的乱码过滤器 --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!-- 指定编码方式 --><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></filter><!-- 映射filter --><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- springmvc的servlet --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定springmvc的配置文件 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!-- 让springmvc随系统启动而启动 --><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

2.7 启动 order-sys 项目

3 服务消费者实现

3.1 创建 user-sys 项目

<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"><modelVersion>4.0.0</modelVersion><groupId>com.bjsxt.consumer</groupId><artifactId>user-sys</artifactId><version>0.0.1-SNAPSHOT</version><!-- 添加httpClient依赖 --><dependencies><dependency><groupId>org.apache.httpcomponents</groupId><version>4.3.5</version><artifactId>httpclient</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency></dependencies></project> 

3.2 拷贝 Order 订单实体类

3.3 创建测试类

package com.sxt.test.client;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;import com.alibaba.fastjson.JSON;
import com.sxt.domain.Order;public class TestHttpClient {public static void main(String[] args) throws ClientProtocolException, IOException {/*** 启动消费者进行服务的消费*///创建NameValuePair对象,封装发送服务提供者的 信息NameValuePair id = new BasicNameValuePair("uid", "1001");/*NameValuePair id1 = new BasicNameValuePair("uid1", "1001");NameValuePair id2 = new BasicNameValuePair("uid2", "1001");*/List<NameValuePair> list = new ArrayList<>();list.add(id);//发送远程的http请求的地址String url="http://localhost:7070/order/loadOrderList01";//创建HttpClient客户端对象HttpClient  client = HttpClients.createDefault();//创建httpPost對象,发送post请求HttpPost post = new HttpPost(url);//封装请求体post.setEntity(new UrlEncodedFormEntity(list,"UTF-8"));//发送具体的http请求HttpResponse response = client.execute(post);//获取响应头消息Header[] headers = response.getAllHeaders();for (Header header : headers) {System.out.println(header.getName()+"-----"+header.getValue());}//获取服务提供者提供的具体数据HttpEntity entity = response.getEntity();//获取http的响应体InputStream content = entity.getContent();int length = 0;char [] buf= new char[1024];//将字节流转换为字符流InputStreamReader is = new InputStreamReader(content);//创建StringBufferStringBuffer sb = new StringBuffer();while((length = is.read(buf))!=-1){sb.append(String.valueOf(buf, 0, length));}System.out.println(sb);//将sb,json字符串转换为order集合List<Order> list1 = JSON.parseArray(sb.toString(), Order.class);for (Order o :list1 ) {System.out.println(o.getId()+"t"+o.getDate()+"t"+o.getTotal());}}
}

使用 Spring 提供的 restTemplate 完成 Http 服务消费

2RestTemplate 介绍 RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访 问远程 Http 服务的方法,能够大大提高客户端的编写效率。

3 服务消费者实现

3.1 业务需求说明

实现:通过红包系统访问订单系统,获得某个用户的订单信息,派发红包.

0dd00e65175d39ae2647aefce544c35a.png

3.2 创建 red-sys 项目

<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"><modelVersion>4.0.0</modelVersion><groupId>com.bjsxt.red.consumer</groupId><artifactId>red-sys</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><properties><!-- spring 依赖 --><spring.version>4.3.18.RELEASE</spring.version><jstl.version>1.2</jstl.version><servlet-api.version>2.5</servlet-api.version><jsp-api.version>2.0</jsp-api.version><jackson.version>2.9.0</jackson.version></properties><dependencies><!-- jsp相关依赖 --><!-- servlet依赖 --><!-- jstl依赖 --><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>${jstl.version}</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>${servlet-api.version}</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jsp-api</artifactId><version>${jsp-api.version}</version><scope>provided</scope></dependency><!-- springmvc依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency></dependencies><build><finalName>red</finalName><plugins><!-- 配置Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version><configuration><path>/red</path><port>8080</port></configuration></plugin></plugins></build>
</project>

3.3 拷贝 Order 订单实体类

拷贝 order-sys 中的实体类

3.4 创建 RedController 类

package com.sxt.controller;import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Entity;@Controller
public class RedController {//注入由spring提供的RestTemplate对象@Autowiredprivate RestTemplate  restTemplate;/*** 发送远程的http请求,消费http服务* 获取订单的集合*/@RequestMapping("/loadOnList01")@ResponseBodypublic List<Order> loadOrderList01(String  uid){//发送到远程服务的urlString url = "http://localhost:7070/order/loadOrderList01";//发送到远程服务的参数MultiValueMap<String, Object> params = new LinkedMultiValueMap<String, Object>();params.add("uid", uid);//通过restTemplate对象发送post请求Order[] orders = restTemplate.postForObject(url, params,Order[].class);//转换为listreturn Arrays.asList(orders);}@RequestMapping("/loadOnList02")@ResponseBodypublic List<Order> loadOrderList02(String  uid){//发送到远程服务的urlString url = "http://localhost:7070/order/loadOrderList02";//发送到远程服务的参数MultiValueMap<String, Object> params = new LinkedMultiValueMap<String, Object>();params.add("uid", uid);//通过restTemplate对象发送post请求ResponseEntity<Order[]> entity = restTemplate.postForEntity(url, params,Order[].class);//get方式//restTemplate.getForEntity(url, responseType, uriVariables);//restTemplate.getForObject(url, params, uriVariables)//获得响应头信息HttpHeaders headers = entity.getHeaders();for (Entry<String, List<String>> e :headers.entrySet()) {System.out.println(e.getKey()+e.getValue());	}  //获取响应状态码int statusCode = entity.getStatusCodeValue();System.out.println(statusCode);//获得远程服务的响应体Order[] orders = entity.getBody();return Arrays.asList(orders);}
}

3.5 配置 springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 扫描controller --><context:component-scan base-package="com.sxt.controller" /><mvc:annotation-driven></mvc:annotation-driven><!-- 实例化RestTemplate对象 --><bean id="restTemplate" class="org.springframework.web.client.RestTemplate"></bean>
</beans>

3.6 配置 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"><display-name>red</display-name><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list><servlet-mapping><servlet-name>default</servlet-name><url-pattern>/favicon.ico</url-pattern></servlet-mapping><!-- 以监听器的方式启动spring容器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 指定spring的配置文件 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext-*.xml</param-value></context-param><!-- POST请求的乱码过滤器 --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><!-- 指定编码方式 --><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></filter><!-- 映射filter --><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- springmvc的servlet --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定springmvc的配置文件 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!-- 让springmvc随系统启动而启动 --><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

3.7 启动 order-sys

3.8 启动访问 red-sys


RPC跨域问题

1、Ajax 跨域介绍

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器 对 JavaScript 施加的安全限制。

6ebb5900c0ba1ace7acb07d7f2d299d9.png

3Ajax 跨域问题

3.1 建立 ajax-origin 项目

<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"><modelVersion>4.0.0</modelVersion><groupId>com.sxt</groupId><artifactId>ajax-origin</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><properties><!-- spring 依赖 --><spring.version>4.3.18.RELEASE</spring.version><jstl.version>1.2</jstl.version><servlet-api.version>2.5</servlet-api.version><jsp-api.version>2.0</jsp-api.version><jackson.version>2.9.0</jackson.version></properties><dependencies><!-- jsp相关依赖 --><!-- servlet依赖 --><!-- jstl依赖 --><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>${jstl.version}</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>${servlet-api.version}</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jsp-api</artifactId><version>${jsp-api.version}</version><scope>provided</scope></dependency></dependencies><build><finalName>ajax</finalName><plugins><!-- 配置Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version><configuration><path>/ajax</path><port>9090</port></configuration></plugin></plugins></build>
</project>

3.2 发送 Ajax 请求

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script type="text/javascript">function  sendAjax(){/* $.post("http://localhost:7070/order/loadOrderList02","uid=1234",function(data){alert(data);}); */$.getJSON("http://localhost:7070/order/loadOrderList03?callback=?","uid=1234",function(data){var str = JSON.stringify(data);alert(str);});}function  doCallback(data){//将json对象转换为字符串var str = JSON.stringify(data);alert(str);}
</script>
</head>
<body><a href="javascript:sendAjax()">sendAjax</a><script src="http://localhost:7070/order/loadOrderList03?uid=9999&callback=doCallback"></script>
</body>
</html>

4Ajax 跨域解决方案

4.1 服务器段解决

服务端设置 response header 中 Access-Control-Allow-Origin 字段 ,服务器段,使用 CORSFilter 过滤器解决跨域问题

通过 CORSFilter 过滤器在服务器端修改 Http 的响应头 Access-Control-Allow-Origin: * Access-Control-Allow-Origin: http://example.com:8080/

修改 order-sys 项目

(1)添加 CORSFilter 依赖

<dependency><groupId>com.thetransactioncompany</groupId><artifactId>cors-filter</artifactId><version>2.5</version><scope>runtime</scope></dependency>

(2) web.xml 配置 CORSFilter

<filter-name>CORS</filter-name>  <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>  <init-param>  <param-name>cors.allowOrigin</param-name>  <param-value>*</param-value>  </init-param>  <init-param>  <param-name>cors.supportedMethods</param-name>  <param-value>GET, POST, HEAD, PUT, DELETE</param-value>  </init-param>  <init-param>  <param-name>cors.supportedHeaders</param-name>  <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>  </init-param>  <init-param>  <param-name>cors.exposedHeaders</param-name>  <param-value>Set-Cookie</param-value>  </init-param>  <init-param>  <param-name>cors.supportsCredentials</param-name>  <param-value>true</param-value>  </init-param>  
</filter>  <filter-mapping>  <filter-name>CORS</filter-name>  <url-pattern>/*</url-pattern>  
</filter-mapping>  

4.2 前端 JSONP 解决

利用 script 标签,不受同源策略的限制,用户从服务请求数据,服务器返回一个带有方法和数据 的 js 代码。

在 js 中,我们直接用 XMLHttpRequest 请求不同域上的数据时,是不可以的。但是,在页面 上引入不同域上的 js 脚本文件却是可以的,jsonp 正是利用这个特性来实现的。

例如: <script src="https://code.jquery.com/jquery-1.12.4.js"></script>

从不同域的服务器直接请求 js 代码,jsonp 就是通过获得不同域的服务器上的 js 代码(js 代码 中包含一个在本地定义的 js 函数和需要获得数据),来获得不同域的数据。

3 修改 order-sys 项目

3.1 注释 web.xml 中 CORSFilter 配置

3.2 添加 fastjson 依赖

<!-- fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency></dependencies>

3.3 修改 OrderController 类

Controller 添加一个接收远程 ajax 请求的方法,该方法后一个接收回调函数的参数.

   /*** 接收json请求,响应js的字符串到客服端* @param uid* @param callback* @return*/@RequestMapping("/loadOrderList03")@ResponseBodypublic String loadOrderList03(String uid,String callback){Order order1 = new Order();order1.setId("111");order1.setTotal(123.0);order1.setDate("2018-10-01");Order order2 = new Order();order2.setId("222");order2.setTotal(1213.0);order2.setDate("2018-10-21");Order order3 = new Order();order3.setId("333");order3.setTotal(1233.0);order3.setDate("2018-10-31");List<Order> list = new ArrayList<>();list.add(order1);list.add(order2);list.add(order3);//函数名+函数的实参String result = callback+"("+JSON.toJSONString(list)+")";return result;}

3.4 启动 order-sys 项目

4 修改 ajax-origin 项目 4.1 导入 juqery 函数库

<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.js"></script>

4.2 发送请求

利用<script src="url?callback=doSomething"></script>发送请求

<script src="http://localhost:7070/order/loadOrderList03?uid=9999&callback=doCallback"></script>

4.3 定义 callback 回调函数

function  doCallback(data){//将json对象转换为字符串var str = JSON.stringify(data);alert(str);}

5jquery 对 jsonp 支持

function  sendAjax(){/* $.post("http://localhost:7070/order/loadOrderList02","uid=1234",function(data){alert(data);}); */$.getJSON("http://localhost:7070/order/loadOrderList03?callback=?","uid=1234",function(data){var str = JSON.stringify(data);alert(str);});}

RPCRMI服务集群部署_消费_服务注册和发现

目标:理解服务的集群部署

理解服务发现

1.1 服务单机部署

将某个应用服务,部署到一台服务器,所有服务消费者的并发访问都发送到一台服务器.

11f9c420b0a49843f1b39cc32487cd7d.png

在系统业务的发展,不露出相应的问题: 高并发访问题: 会出现系统资源不够用(带宽,cpu,内存)等等 系统的单节点故障: 当单节点服务器出现宕机故障的时候,会出现服务访问没法访问的 问

1.2 服务的集群部署

将某个应用服务部署到,同时部署到 n 个服务器节点,由 n 个服务器节点对外提供相同服务. 同时可以提供备用节点服务器.

e134781121d6406ea1c209a3c4c25919.png

通过集群部署的方式可以解决,服务的高并发访问和单节点故障问题: 高并发访问: 通过特定的负载均衡(Load Balance)算法,将并发访问的请求,分发到不同节点的服务器进行处理,以将每一台服务器的负载压力,实现负载均衡。

单节点故障: 当实现服务集群部署的时候,单个服务器节点宕机,可以由其他正常的服务器节点,正 常向外提供服务,不会出现服务的不可访问问题,实现服务的(HA)高可用

3RMI 模拟服务器集群部署

3.1 发布集群服务

启动程序三次,每次启动修改端口号,实现服务的集群部署

3.2RMI 消费集群服务

package com.sxt.app;import java.rmi.Naming;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;import com.sxt.service.UserService;public class consumerApp {public static void main(String[] args) {List<String> urls = new ArrayList<String>();urls.add("rmi://localhost:7777/rmi");urls.add("rmi://localhost:8888/rmi");urls.add("rmi://localhost:9999/rmi");String url = null;try {while(true){//通过随机的负载均衡算法,产生随机的访问地址int index = ThreadLocalRandom.current().nextInt(urls.size());url = urls.get(index);UserService  service = (UserService)Naming.lookup(url);System.out.println("获取的远程服务的代理对象:"+service.getClass().getName());			//通过远程服务的代理对象代用远程代理方法String result = service.helloRmi("///"+url+"--------------rmi");System.out.println("result"+result);Thread.sleep(3000);}} catch (Exception e) {urls.remove(url);			e.printStackTrace();}}
}

4、 服务注册与发现

9c6dd6b49802d81f2642b1461eee7a4a.png

(0)服务容器负责启动,加载,运行服务提供者。

(1)服务提供者在启动时,向注册中心注册自己提供的服务 URL。

(2)服务消费者在启动时,向注册中心订阅自己所需的服务。

(3)注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送 变更数据给消费者。

(4)服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如 果调用失败,再选另一台调用。

让消费能够感知到服务提供者的状态发生了变化(宕机,重启)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MFC项目实战(1)文件管理器--准备篇

本程序主要实现如下功能&#xff1a; 程序通过左边的树形控件显示本地计算机中目录的结构&#xff0c;右边的列表控件则负责响应树形控件中选择的目录节点并把此节点中的所有项在列表框中显示出来&#xff0c;列表框支持奇偶行颜色设置&#xff0c;选中颜色设置和热点颜色设置&…

使用tab键分割的文章能快速转换成表格。( )_EXCEL的163种使用技巧集锦-42~62

本文主要讲述了EXCEL的163种使用技巧其中20条技巧&#xff0c;待163种使用技巧全部讲述完成后&#xff0c;如有需要&#xff0c;各位看官可在评论中留下邮箱&#xff0c;小编会将整理的WORD版发给大家。42. 快速查找工作簿 你可以利用在工作表中的任何文字进行搜寻&#xff0c;…

android通过代码设置铃声_第六十四回:Android中UI控件之SeekBar

各位看官们&#xff0c;大家好&#xff0c;上一回中咱们说的是Android中UI控件之ProgressBar的例子&#xff0c;这一回咱们的例子是UI控件之SeekBar。闲话休提&#xff0c;言归正转。让我们一起Talk Android吧&#xff01;看官们&#xff0c;SeekBar通常翻译为拖动条&#xff0…

利旧IBM X3650m2 安装esxi5.1提供云桌面(备忘)

上面左边是我的个人微信&#xff0c;如需进一步沟通&#xff0c;请加微信。 右边是我的公众号“Openstack私有云”&#xff0c;如有兴趣&#xff0c;请关注。公司有一台旧服务器&#xff0c;原来的IBM X3650m2 服务器&#xff0c;2物理CPU&#xff0c;24G内存&#xff0c;8块3…

asp登录页面跳转到注册页面_Java 添加页面跳转按钮到PDF文档

概述当我们在查阅含有大量页面的PDF时&#xff0c;可通过在页面上添加跳转按钮来实现页面转换&#xff0c;以达到节约时间&#xff0c;提高效率的目的。本文将通过Java程序来演示如何给PDF文档添加页面跳转按钮。通常来说跳转可分为两种情况&#xff1a;一是跳转至特殊页面(首页…

确定最佳聚类数matlab代码_详解DBSCAN聚类

使用DBSCAN标识为员工分组照片由Ishan seefromthesky 在 Unsplash拍摄基于密度的噪声应用空间聚类(DBSCAN)是一种无监督的ML聚类算法。无监督的意思是它不使用预先标记的目标来聚类数据点。聚类是指试图将相似的数据点分组到人工确定的组或簇中。它可以替代KMeans和层次聚类等流…

Arrays.asList 使用细节

通常初始化后使用如下&#xff0c;但是报错 UnsupportOperationException.... 根据提示信息&#xff0c;就是调用add()方法时抛出了异常。顺着堆栈信息往上找&#xff0c;提示的是AbstractList类的108行出了异常&#xff0c;这一行所在方法的具体实现如下&#xff1a; //108行 …

python list元素合并_python list 合并连接字符串的方法

python list 合并连接字符串的方法 更新时间&#xff1a;2013年03月09日 22:02:18 作者&#xff1a; python 列表合并字符串&#xff0c;我们一般会用到字符串的join方法来操作。下面通过代码的形式&#xff0c;详细的说下list怎么拼成字符串&#xff1f; 相关文章这篇文章主要…

单片机按键防抖程序_这些单片机按键设计方案,请拿好,不谢!

在单片机系统里&#xff0c;按键是常见的输入设备&#xff0c;在本文中介绍几种按键硬件、软件设计方面的技巧。一般的在按键的设计上&#xff0c;一般有四种方案&#xff0c;创客学院带你零基础学习电子产品设计。一是GPIO口直接检测单个按键&#xff0c;如图1.1所示;二是按键…

Oracle 11G 安装详解

oracle官网下载地址&#xff1a;http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 官网下载需要注册orcale账号&#xff0c;比较繁琐&#xff0c;这里直接放已经下载好的安装包链接 Oracle11G下载链接: https://pan.baidu.com/s/1v6oD4jAt…

kubeadm部署k8s_用 kubeadm 部署生产级 k8s 集群

概述kubeadm 已⽀持集群部署&#xff0c;且在1.13 版本中 GA&#xff0c;⽀持多 master&#xff0c;多 etcd 集群化部署&#xff0c;它也是官⽅最为推荐的部署⽅式&#xff0c;⼀来是由它的 sig 组来推进的&#xff0c;⼆来 kubeadm 在很多⽅⾯确实很好的利⽤了 kubernetes 的许…

统计学习方法概论---分类问题

为什么80%的码农都做不了架构师&#xff1f;>>> 分类问题 转载于:https://my.oschina.net/liyangke/blog/2945185

CENTOS7 Python3.7 PyAudio 安装

2019独角兽企业重金招聘Python工程师标准>>> 出现错误: gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -fPIC -I/usr/local/python371/include/python3.7m -c src/_portaudiomodule.c -o build/temp.linux-aarch64-3.7/src/…

bash for循环_Bash 中的 For 循环

循环是编程语言的基本概念之一。当你想要一遍又一遍地运行一系列命令直到达到某个条件后终止退出时&#xff0c;循环很方便。在诸如 Bash 之类的脚本语言中&#xff0c;循环对于自动执行重复性任务非常有用。在 Bash 脚本中有3个基本的循环结构&#xff0c;for 循环&#xff0c…

linux 信号_Linux的信号和线程

Linux的信号和线程-Tech Talk 让技术发出声音​www.ttalk.im什么是线程线程&#xff0c;有时被称为轻量级进程(Lightweight Process&#xff0c;LWP&#xff09;&#xff0c;是程序执行流的最小单元。一个标准的线程由线程ID&#xff0c;当前指令指针(PC&#xff09;&#xff0…

python 数据结构

一. 深入链表 先来介绍一些链表具备的一些常用方法&#xff1a; append(x) : 把一个元素添加到链表的结尾 extend(L) : 将另外一个链表合并到该链表中 insert(i,x) : 插入一个元素到指定位置的前面 remove(x) : 删除链表中第一个值为x的元素 如果没有这样的元素 则返回错误 pop…

go语言项目优化(经验之谈)

1 Go的应用场景 在斗鱼我们将GO的应用场景分为以下三类&#xff0c;缓存类型数据&#xff0c;实时类型数据&#xff0c;CPU密集型任务。这三类应用场景都有着各自的特点。 ● 缓存类型数据在斗鱼的案例就是我们的首页&#xff0c;列表页&#xff0c;这些页面和接口的特点是不同…

python交互界面用图片当背景_wxPython实现窗口用图片做背景

本文实例为大家分享了wxPython实现窗口用图片做背景的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 效果图&#xff1a;实现代码&#xff1a; #!/usr/bin/env python # -*- encoding:utf-8 -*- import wx class MyPanel(wx.Panel): def __init__(self,parent,id): …

c 字符串转数字_C语言实现十进制转216进制、十六进制转十进制

1、十进制转2&#xff5e;16进制【问题描述】从键盘输入十进制整数num及转换的进制数base&#xff0c;将整数num转换为base进制(base取值范围为 2&#xff5e;16)。方法为&#xff1a;十进制数除base取余法&#xff0c;即十进制数除以base&#xff0c;余数为权位上的数&#xf…