Dubbo разоблачить HTTP службы

Dubbo разоблачить HTTP службы

   点关注不迷路,欢迎再访!		

предисловие

Обычно Даббо услуги являются внутренними для внутренних вызовов, но могут потребоваться для предоставления услуг для внешнего использования, а также не могут иметь ограничений на использовании языка. В этой главе говорили о не так сложно, это просто не нужно разрешение испытать разнообразные Даббо предоставления внешних услуг для службы HTTP.

Препараты

Ниже приведены некоторые из знаний, охватываемых в этой статье:

Весна знание
Java отражения знаний
SpringMVC знаний

其实思路很简单,利用SpringMVC提供一个HTTP接口。在该接口中通过入参进行反射找到具体的dubbo服务实现进行调用。

HttpProviderConf класс конфигурации

Прежде всего, необходимо определить класс для HttpProviderConf имени пакета, чтобы сохранить заявление необходимо для оказания услуг, в конце концов, когда мы отразили необходимость использовать полное имя класса:

public class HttpProviderConf {
    /**
     * 提供http访问的包
     */
    private List<String> usePackage ;

	public List<String> getUsePackage() {
		return usePackage;
	}

	public void setUsePackage(List<String> usePackage) {
		this.usePackage = usePackage;
	}
    
}

В ответ на запрос справочной, ссылки

HttpRequest 入 参

public class HttpRequest {
	
	private String param ;//入参
    private String service ;//请求service
    private String method ;//请求方法
    
	public String getParam() {
		return param;
	}
	public void setParam(String param) {
		this.param = param;
	}
	public String getService() {
		return service;
	}
	public void setService(String service) {
		this.service = service;
	}
	public String getMethod() {
		return method;
	}
	public void setMethod(String method) {
		this.method = method;
	}
}

Где пары используются для хранения параметров в реальный масштаб времени обслуживания вызова Дабб, входящие вызовы JSon при разборе в конкретный объект параметров.
Dubbo имя службы пакета услуг для хранения объявленных интерфейса API.
метод является реальным именем вызова метода.

HttpResponse ответ

public class HttpResponse implements Serializable{
	
	private static final long serialVersionUID = -6296842759601736401L;	
	private boolean success;// 成功标志
	private String code;// 信息码
	private String description;// 描述
	
	public boolean isSuccess() {
		return success;
	}
	public void setSuccess(boolean success) {
		this.success = success;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
}

Вот только инкапсулирует данные и сервисы HTTP ответа.

Контроллер Разоблачение услуги

@Controller
@RequestMapping("/dubboAPI")
public class DubboController implements ApplicationContextAware {

	private final static Logger logger = LoggerFactory.getLogger(DubboController.class);

	@Autowired
	private HttpProviderConf httpProviderConf;
	// 缓存作用的map
	private final Map<String, Class<?>> cacheMap = new HashMap<String, Class<?>>();
	protected ApplicationContext applicationContext;

	@ResponseBody
	@RequestMapping(value = "/{service}/{method}", method = RequestMethod.GET)
	public String api(HttpRequest httpRequest, HttpServletRequest request, @PathVariable String service,
			@PathVariable String method) {
		logger.info("ip:{}-httpRequest:{}");
		String invoke = invoke(httpRequest, service, method);
		logger.debug("callback :" + invoke);
		return invoke;

	}

	private String invoke(HttpRequest httpRequest, String service, String method) {
		httpRequest.setService(service);
		httpRequest.setMethod(method);
		HttpResponse response = new HttpResponse();

		logger.debug("input param:" + JSON.toJSONString(httpRequest));

		if (!CollectionUtils.isEmpty(httpProviderConf.getUsePackage())) {
			boolean isPac = false;
			for (String pac : httpProviderConf.getUsePackage()) {
				if (service.startsWith(pac)) {
					isPac = true;
					break;
				}
			}
			if (!isPac) {
				// 调用的是未经配置的包
				logger.error("service is not correct,service=" + service);
				response.setCode("2");
				response.setSuccess(false);
				response.setDescription("service is not correct,service=" + service);
			}

		}
		try {
			Class<?> serviceCla = cacheMap.get(service);
			if (serviceCla == null) {
				serviceCla = Class.forName(service);
				logger.debug("serviceCla:" + JSON.toJSONString(serviceCla));

				// 设置缓存
				cacheMap.put(service, serviceCla);
			}
			Method[] methods = serviceCla.getMethods();
			Method targetMethod = null;
			for (Method m : methods) {
				if (m.getName().equals(method)) {
					targetMethod = m;
					break;
				}
			}

			if (method == null) {
				logger.error("method is not correct,method=" + method);
				response.setCode("2");
				response.setSuccess(false);
				response.setDescription("method is not correct,method=" + method);
			}

			Object bean = this.applicationContext.getBean(serviceCla);
			Object result = null;
			Class<?>[] parameterTypes = targetMethod.getParameterTypes();
			if (parameterTypes.length == 0) {
				// 没有参数
				result = targetMethod.invoke(bean);
			} else if (parameterTypes.length == 1) {
				Object json = JSON.parseObject(httpRequest.getParam(), parameterTypes[0]);
				result = targetMethod.invoke(bean, json);
			} else {
				logger.error("Can only have one parameter");
				response.setSuccess(false);
				response.setCode("2");
				response.setDescription("Can only have one parameter");
			}
			return JSON.toJSONString(result);

		} catch (ClassNotFoundException e) {
			logger.error("class not found", e);
			response.setSuccess(false);
			response.setCode("2");
			response.setDescription("class not found");
		} catch (InvocationTargetException e) {
			logger.error("InvocationTargetException", e);
			response.setSuccess(false);
			response.setCode("2");
			response.setDescription("InvocationTargetException");
		} catch (IllegalAccessException e) {
			logger.error("IllegalAccessException", e);
			response.setSuccess(false);
			response.setCode("2");
			response.setDescription("IllegalAccessException");
		}
		return JSON.toJSONString(response);
	}

	/**
	 * 获取IP
	 * 
	 * @param request
	 * @return
	 */
	private String getIP(HttpServletRequest request) {
		if (request == null)
			return null;
		String s = request.getHeader("X-Forwarded-For");
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s)) {

			s = request.getHeader("Proxy-Client-IP");
		}
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s)) {

			s = request.getHeader("WL-Proxy-Client-IP");
		}
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s)) {
			s = request.getHeader("HTTP_CLIENT_IP");
		}
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s)) {

			s = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (s == null || s.length() == 0 || "unknown".equalsIgnoreCase(s)) {

			s = request.getRemoteAddr();
		}
		if ("127.0.0.1".equals(s) || "0:0:0:0:0:0:0:1".equals(s))
			try {
				s = InetAddress.getLocalHost().getHostAddress();
			} catch (UnknownHostException unknownhostexception) {
				return "";
			}
		return s;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
}
  • Первое определение DubboController, и использование внешнего воздействия SpringMVC примечаний HTTP службы.

  • Org.springframework.context.ApplicationContextAware реализует классы, которые реализуют setApplicationContext () метод используется для инициализации Spring объект контекста, может быть получен после соответствующего объекта контейнера.

  • Суть метода Invoke ().

  • Когда вы звоните: HTTP: //127.0.0.1: 8080 / Dubbo-провайдер / dubboAPI / com.dubbo.service.IDubboService / GetUser.

  • Конкретные примеры вышеупомянутого вызова. Во-первых com.dubbo.service.IDubboService, GetUser назначен HTTPRequest в женьшень.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	<!-- 定义了提供方应用信息,用于计算依赖关系。在dubbo-admin 或 dubbo-monitor 会显示这个名字,方便识别 -->
	<dubbo:application name="admin-provider" owner="admin" organization="dubbox"/>
	<!-- 使用zookeeper 注册中心暴露服务,注意要先开启 zookeeper -->
	<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
	<!-- 用dubbo协议在20880端口暴露服务 -->
	<dubbo:protocol name="dubbo" port="20880"/>
	<!-- 用dubbo 协议实现定义好的 api 接口 -->
	<dubbo:service interface="com.dubbo.service.IDubboService" ref="dubboService" protocol="dubbo"/>
	<dubbo:service interface="com.dubbo.service.IUserService" ref="userService" protocol="dubbo"/>
	<!--dubbo服务暴露为http服务-->
    <bean class="com.crossoverJie.dubbo.http.conf.HttpProviderConf">
        <property name="usePackage">
            <list>
            	   <!--需要暴露服务的接口包名,可多个-->
                <value>com.dubbo.service</value>
            </list>
        </property>
    </bean>
</beans>

Что имя пакета com.dubbo.service они нуждаются в экспозиции, может несколько.

  • Затем введите удаленный интерфейс класса отражения приобретенного в кэше карты, если она приобретается не за счет приобретения отражения, и установленное значение карты в кэш, так что не каждое приобретение отражение, система накладные расходы могут быть сохранены (отражая трату ресурсов ).
  • Затем определяется, является ли входящий интерфейс метода GetUser.
  • Удалить список параметров метода, если аргумент не вызывается непосредственно.
  • Если есть параметры, определить число. Here до запуска только один параметр. Это может проходить только тип BO в режиме реального времени Даббо вызовов, в частности, список параметров можно записать в BO. Потому что, если есть больше времени, чтобы решить в течение не может JSON быть назначены два объекта параметра идти.
  • После вызова, вызов возвращает данные, которые будут возвращены.
Опубликовано 101 оригинальные статьи · вона похвала 33 · просмотров 20000 +

рекомендация

отblog.csdn.net/qq_39443053/article/details/103964194