springboot-发布与调试REST服务02--实现跨域

版权声明:本文为博主原创文章,经博主允许,可自由共享,尽量不要用于商业用途。 https://blog.csdn.net/matrixbbs/article/details/90640361

发布与调用REST服务

  • 可以用SOAP
  • 也可以用REST,本例仍然以REST为例

表述性状态转移===REST

  • 是一种架构风格
  • 也是一种轻量级的基于HTTP协议的Web Service风格
  • 是一种设计原则
  • 也是一种设计思想

整体示例搭建思路

  • 搭建服务器

  • 搭建客户端

    • 测试并调用REST服务,用8085,端口,在application.properties完成相应的设置即可
    • 使用RestTemplate类来调用服务,这个类是Spring Framework提供的
    • 测试方式三种
      • 1 使用main直接跑方法来访问REST服务
      • 2 使用JUNIT测试方法来访问REST服务
      • 3 使用WEB中的控制器来访问REST服务
    • 项目名:spring-rest-client

共同的部分—两个项目中都会用到,重复定义

本实例中,在服务器项目中,将它定义为一个内部类,直接用即可

  • 流转对象定义:Person.java
package com.fhzheng.demo;
// 流转数据对象
public class Person{
	String name;
	Integer age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
}

1 服务器项目实现

在这里插入图片描述
具体服务器代码

package com.fhzheng.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController 
public class SpringRestServerApplication {

	// 启动器
	public static void main(String[] args) {
		SpringApplication.run(SpringRestServerApplication.class, args);
	}
	
	// 控制器
	@GetMapping(value="/person/{name}",produces = MediaType.APPLICATION_JSON_VALUE)
	public Person person(@PathVariable String name) {
		Person p = new Person();
		p.setName(name);
		p.setAge(33);
		return p;
	}
	
	// 流转数据对象
	static class Person{
		String name;
		Integer age;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public Integer getAge() {
			return age;
		}
		public void setAge(Integer age) {
			this.age = age;
		}
	}

}

2 客户端项目实现

在这里插入图片描述
具体代码实现
Person.java之前已经提供了
MyService.java

package com.fhzheng.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


@Service
public class MyService {

	@Autowired
	private RestTemplateBuilder builder;
	
	@Bean
	public RestTemplate restTemplate() {
		return builder.rootUri("http://localhost:8080").build();
	}
	
	public Person useBuilder() {
		Person p = restTemplate().getForObject("/person/fhzheng999", Person.class);
		return p;
	}
}

RestTemplateMain .java

package com.fhzheng.demo;

import org.springframework.web.client.RestTemplate;

public class RestTemplateMain {

	/**
	 * 	用一个普通方法,直接完成对REST服务的请求
	 * @param args
	 */
	public static void main(String[] args) {

		RestTemplate tpl = new RestTemplate();
		Person p = tpl.getForObject("http://localhost:8080/person/fhzheng777", Person.class);
		System.out.println(p.getName()+"---"+p.getAge());
	}

}

JUNIT测试代码SpringRestClient1ApplicationTests.java

package com.fhzheng.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE)	//保证web容器不被启动,只做单元测试
public class SpringRestClient1ApplicationTests {

	@Autowired 
	private MyService myService;
	
	@Test
	public void testUserTemplate() {
		Person p = myService.useBuilder();
		System.out.println(p.getName() + "==="+ p.getAge());
	}
	
	@Test
	public void contextLoads() {
	}

}

application.properties配置文件内容
这里的服务器采用的是默认端口发布服务,即8080
客户端调用服务,客户端发布端口为8085

# server
server.port = 8085

客户端启动器和控制器实现

package com.fhzheng.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@RestController
public class SpringRestClient1Application {

	public static void main(String[] args) {
		SpringApplication.run(SpringRestClient1Application.class, args);
	}

	// 控制器
	/**
	 * 	用跨域方式,完成对REST服务的请求
	 * 	注意,WEB服务启动起来时,客户端端口号不能和服务器端端口号重叠,保证跨域状态
	 * @return
	 */
	@GetMapping(value="/client")
	public Person clientGetPerson() {
		RestTemplate tpl = new RestTemplate();
		Person p = tpl.getForObject("http://localhost:8080/person/fhzheng777", Person.class);
		System.out.println(p.getName()+"---"+p.getAge());
		return p;
	}
}

运行结果

服务端运行测试

在这里插入图片描述

客户端运行测试

1 main测试结果

在这里插入图片描述

2 JUNIT测试结果

在这里插入图片描述

3 客户端WEB测试运行结果

在这里插入图片描述

后记

  • RestTemplate只是众多的REST客户端中的一个。还有很多,诸如:
    • Feign框架
    • Restlet框架
    • CXF框架
      它们都可以实现对REST服务的调用,使用它们,简单说就是:简化了发起HTTP请求以及处理响应的过程,并且支持REST。为什么说简化了呢

什么是RestTemplate

从 3.0 版本开始,Spring 提供了 RestTemplate 作为用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。我们自己封装的HttpClient,通常都会有一些模板代码,比如建立连接,构造请求头和请求体,然后根据响应,解析响应信息,最后关闭连接。RestTemplate是Spring中对HttpClient的再次封装,简化了发起HTTP请求以及处理响应的过程,抽象层级更高,减少消费者的模板代码,使冗余代码更少。其实仔细想想Spring Boot下的很多XXXTemplate类,它们也提供各种模板方法,只不过抽象的层次更高,隐藏了更多细节而已。顺便提一下,Spring Cloud有一个声明式服务调用Feign,是基于Netflix Feign实现的,整合了Spring Cloud Ribbon与 Spring Cloud Hystrix,并且实现了声明式的Web服务客户端定义方式。
本质上Feign是在RestTemplate的基础上对其再次封装,由它来帮助我们定义和实现依赖服务接口的定义。

猜你喜欢

转载自blog.csdn.net/matrixbbs/article/details/90640361