restful不是一个框架,称为一种编码更烦更贴切吧,其核心类位于spring-web.jar中,即RestTemplate.class

restful是rpc通过http协议的一种实现方式,和webservice一样,请参阅我的其他文章

今天我将在springmvc环境中进行演示,首先请看我其他博客文章下载整理好的源码,整理好的源码可以直接用于商业项目开发

整理好的代码项目结构如下:

本次讲的restful大致如下

文采不好,开始贴代码:

① 常量工具类,用于保存http、:、?、=、&这些的

package xiaochangwei.zicp.net.restful.tools;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; public class CommonUtils
{
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); private static ObjectMapper objectMapper = new ObjectMapper(); public static String HTTP_SLASH = "/"; public static String HTTP_COLON = ":"; public static String HTTP_QUESTION_MARK = "?"; public static String HTTP_EQUAL_MARK = "="; public static String HTTP_AMPERSAND = "&"; public static int INIT_VALUE = -1; public static String changeObjectToJsonStr(Object object) throws JsonProcessingException
{
String content = objectMapper.writeValueAsString(object); logger.debug("content = [{}].", content);
return content;
} public static <T> T changeJsonStrToObject(String content, Class<T> valueType)
throws JsonParseException, JsonMappingException, IOException
{
return objectMapper.readValue(content, valueType);
}
}

② 模块枚举定义类

package xiaochangwei.zicp.net.restful.tools;

public enum ModuleEnum {
MODULE_SERVICE("services", 1),
MODULE_ACCESS("icp/url", 2),
MODULE_SMSSend("sms/Api/Send.do", 3),
MODULE_TEST("project-web/restful/restfulService", 4),; private String name; private int index; private ModuleEnum(String name, int index) {
this.name = name;
this.index = index;
} public static String getName(int index) {
for (ModuleEnum m : ModuleEnum.values()) {
if (m.getIndex() == index) {
return m.name;
}
}
return null;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getIndex() {
return index;
} public void setIndex(int index) {
this.index = index;
}
}

③ 参数封装类

package xiaochangwei.zicp.net.restful.tools;

import java.util.Date;
import java.util.HashMap;
import java.util.Map; import org.springframework.http.HttpMethod; public class ParamEntity
{
// IP地址。
private String ipaddr; // IP端口。
private String port;

④ 核心调用类

package xiaochangwei.zicp.net.restful.tools;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate; @SuppressWarnings("deprecation")
public class HttpClientUtils
{
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); private static String HTTP_PROTOCOL = "http://"; public static ResponseEntity<String> Execute(ParamEntity paramEntity)
{
HttpClient httpClient = null; try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null); SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), Integer.valueOf(paramEntity.getPort())));
registry.register(new Scheme("https", sf, Integer.valueOf(paramEntity.getPort()))); ClientConnectionManager ccm = new ThreadSafeClientConnManager(registry);
httpClient = new DefaultHttpClient(ccm);
} catch (Exception e) {
logger.info("httpclient创建错误.");
} HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
httpComponentsClientHttpRequestFactory.setConnectTimeout(120*1000);
httpComponentsClientHttpRequestFactory.setReadTimeout(120*1000);
RestTemplate rt = new RestTemplate(httpComponentsClientHttpRequestFactory); String url = HttpClientUtils.generateUrl(paramEntity); HttpEntity<String> requestEntity = HttpClientUtils.generateHttpEntity(paramEntity); try
{
System.out.println("httpMethod = " + paramEntity.getHttpMethod());
System.out.println("url = " + url);
System.out.println("requestEntity = " + requestEntity); ResponseEntity<String> responseEntity =
rt.exchange(url, paramEntity.getHttpMethod(), requestEntity, String.class); logger.debug("responseEntity = [{}].", responseEntity);
System.out.println("responseEntity = " + responseEntity);
return responseEntity;
}
catch (Exception e)
{
System.out.println("info: " + e.getMessage());
logger.debug("error info: = [{}].", e.getMessage());
return generateRespWhenException(e);
}
} private static ResponseEntity<String> generateRespWhenException(Exception e)
{
String msg = e.getMessage();
String[] strs = msg.split(" ");
HttpStatus retCode;
try
{
retCode = HttpStatus.valueOf(Integer.valueOf(strs[0]));
}
catch (NumberFormatException ex)
{
retCode = HttpStatus.SERVICE_UNAVAILABLE;
} return new ResponseEntity<String>(retCode);
} private static String generateUrl(ParamEntity paramEntity)
{
StringBuilder url = new StringBuilder(); url.append(HTTP_PROTOCOL)
.append(paramEntity.getIpaddr())
.append(CommonUtils.HTTP_COLON)
.append(paramEntity.getPort())
.append(CommonUtils.HTTP_SLASH); if (!StringUtils.isEmpty(paramEntity.getVersion()))
{
url.append(paramEntity.getVersion()).append(CommonUtils.HTTP_SLASH);
} ModuleEnum module = paramEntity.getModule();
switch (module)
{
case MODULE_SERVICE:
addServiceUri(url);
break;
case MODULE_SMSSend:
addSMSSendUri(url, paramEntity);
break;
case MODULE_TEST:
addUserUri(url, paramEntity);
break;
default:
logger.error("module [{}] does not exist.", module.getName());
break;
} logger.debug("url = [{}].", url.toString());
return url.toString();
} private static HttpEntity<String> generateHttpEntity(ParamEntity frontInfo)
{
String data = frontInfo.getData(); HttpHeaders headers = new HttpHeaders();
for (String headerKey : frontInfo.getHeadersMap().keySet())
{
String headerValue = frontInfo.getHeadersMap().get(headerKey);
if (!StringUtils.isEmpty(headerValue))
{
headers.add(headerKey, headerValue);
}
} HttpEntity<String> requestEntity = new HttpEntity<String>(data, headers); logger.debug("requestEntity = [{}].", requestEntity);
return requestEntity;
} private static void addServiceUri(StringBuilder url)
{
url.append(ModuleEnum.MODULE_SERVICE.getName());
} private static void addUserUri(StringBuilder url, ParamEntity frontInfo)
{
url.append(ModuleEnum.MODULE_TEST.getName()); if (!StringUtils.isEmpty(frontInfo.getUser_id()))
{
url.append(CommonUtils.HTTP_SLASH).append(frontInfo.getUser_id());
}
} private static void addSMSSendUri(StringBuilder url, ParamEntity frontInfo)
{
url.append(ModuleEnum.MODULE_SMSSend.getName()); boolean hasParam = false;
hasParam = addParamsToUri(hasParam, "SpCode", frontInfo.getSmsSpCode(), url);
hasParam = addParamsToUri(hasParam, "LoginName", frontInfo.getSmsLoginName(), url);
hasParam = addParamsToUri(hasParam, "Password", frontInfo.getSmsPassword(), url);
hasParam = addParamsToUri(hasParam, "MessageContent", frontInfo.getSmsMessageContent(), url);
hasParam = addParamsToUri(hasParam, "UserNumber", frontInfo.getSmsUserNumber(), url);
hasParam = addParamsToUri(hasParam, "SerialNumber", frontInfo.getSmsSerialNumber(), url);
hasParam = addParamsToUri(hasParam, "ScheduleTime", frontInfo.getSmsScheduleTime(), url);
hasParam = addParamsToUri(hasParam, "f", frontInfo.getSmsf(), url);
} private static boolean addParamsToUri(boolean hasParam, String descripition, String param, StringBuilder url)
{
if (!StringUtils.isEmpty(param) && !param.equals("null"))
{
if (hasParam)
{
url.append(CommonUtils.HTTP_AMPERSAND);
}
else
{
url.append(CommonUtils.HTTP_QUESTION_MARK);
}
url.append(descripition).append(CommonUtils.HTTP_EQUAL_MARK).append(param); return true;
} return false;
} private static class MySSLSocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); public MySSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore); TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
} public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return null;
}
}; sslContext.init(null, new TrustManager[] { tm }, null);
} @Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
} @Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}

⑤ 调用入口

package xiaochangwei.zicp.net.restful.operation.impl;

import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component; import xiaochangwei.zicp.net.restful.operation.RestfulTestOperation;
import xiaochangwei.zicp.net.restful.tools.ParamEntity;
import xiaochangwei.zicp.net.restful.tools.HttpClientUtils;
import xiaochangwei.zicp.net.restful.tools.ModuleEnum; /**
* @author http://www.cnblogs.com/xiaochangwei
* @date 2016年4月20日
*
*/
@Component
public class RestfulTestOperationImpl implements RestfulTestOperation { public ResponseEntity<String> restfulTestMethod(ParamEntity paramEntity) {
paramEntity.setModule(ModuleEnum.MODULE_TEST); paramEntity.setHttpMethod(HttpMethod.POST); ResponseEntity<String> responseEntity = HttpClientUtils.Execute(paramEntity); return responseEntity;
}
}

⑥ service层参数封装、调用、返回结果处理类

package xiaochangwei.zicp.net.service.restful;

import java.util.HashMap;
import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import xiaochangwei.zicp.net.restful.operation.RestfulTestOperation;
import xiaochangwei.zicp.net.restful.tools.ParamEntity; /**
* @author http://www.cnblogs.com/xiaochangwei
* @date 2016年4月20日
*
*/
@Service
public class RestfulTestServiceImpl implements RestfulTestService { @Autowired
private RestfulTestOperation restfulTestOperation; public String restfulTestMethod() {
ParamEntity info = new ParamEntity();
Map<String, Map<String, Object>> dataMap = new HashMap<String, Map<String, Object>>();
Map<String, Object> userEntity = new HashMap<String, Object>();
userEntity.put("default_project_id", "pid");
userEntity.put("description", "user.getDescription()");
userEntity.put("domain_id", "default");
userEntity.put("email", "user.getEmail()");
userEntity.put("enabled", true);
userEntity.put("name", "user.getUsername()");
userEntity.put("password", "user.getStrPassword()");
dataMap.put("user", userEntity);
String data = JSON.toJSONString(dataMap);
info.setData(data); info.setIpaddr("127.0.0.1");
info.setPort("808");
ResponseEntity<String> response = restfulTestOperation.restfulTestMethod(info);
// 当创建某个用户失败时
if (response == null || !response.getStatusCode().equals(HttpStatus.CREATED)) {
throw new RuntimeException("调用接口创建用户失败!");
} else {
JSONObject object = JSONObject.parseObject(response.getBody().toString());
JSONObject userJson = JSONObject.parseObject(object.getString("user"));
System.out.println("解析body为json后的用户id为:"+userJson.getString("id"));
//return userJson.getString("id");
return response.getBody().toString();
}
} }

⑦ controller层测试类,包含调用入口和服务方法,此处为静态返回,可以根据具体业务书写,和常见代码一样

package xiaochangwei.zicp.net.web.controller;

import java.util.HashMap;
import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.alibaba.fastjson.JSON; import xiaochangwei.zicp.net.entity.TestEntity;
import xiaochangwei.zicp.net.service.restful.RestfulTestService; /**
* @author http://www.cnblogs.com/xiaochangwei
* @date 2016年4月20日
*
*/
@Controller
@RequestMapping("restful")
public class RestfulTestController { @Autowired
private RestfulTestService restfulTestService; /**
* 处理restClient请求的的方法体
*/
@RequestMapping("restfulService")
public ResponseEntity<String> testRestClientAdd(
@RequestHeader("Accept") String Accept, @RequestBody String userStr) {
System.out.println("接收到的请求信息-Accept:" + Accept);
System.out.println("接收到的请求信息-body:" + userStr);
// 可以根据请请进行业务处理,这里略了 只是打印出来确定消息传递过来没 // 返回处理结果给调用者
TestEntity en = new TestEntity();
en.setId(1);
en.setName("name1"); Map<String, Object> map = new HashMap<String, Object>();
map.put("user", en);
String body = JSON.toJSONString(map);
System.out.println("准备返回给调用者的body content:" + body); ResponseEntity<String> responseEntity = new ResponseEntity<String>(
body, HttpStatus.CREATED);
return responseEntity;
} /**
* 调用rest接口方法进行rpc调用
*/
@RequestMapping("restfulClientCall")
public @ResponseBody String t() {
return restfulTestService.restfulTestMethod();
}
}

⑧ 见证奇迹的时候又到了

输入  http://www.xiaochangwei.com:808/project-web/restful/restfulClientCall  进行调用,restful会访问我们这个controller中的restfulService

同时控制台也看到如下信息,证明我们的调用成功

至此,restful使用讲解完毕,不过需要提醒的时,restful是通过http协议进行传输的,同等条件下速度比tcp慢,所以实时性较高请使用tcp实现的rpc或者采用jms

相关技术均可以通过我的博客了解学习到,请锁定关注。

Restful 介绍及SpringMVC+restful 实例讲解的更多相关文章

  1. 【Spring】SpringMVC入门示例讲解

    目录结构: // contents structure [-] SpringMVC是什么 Spring MVC的设计原理 SpringMVC入门示例 1,复制Jar包 2,Web.xml文件 3,My ...

  2. RESTful介绍和使用教程

    出自:https://blog.csdn.net/x541211190/article/details/81141459 一.REST起源REST(Representational State Tra ...

  3. 这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)(转)

    前言 在Andrroid开发中,网络请求十分常用 而在Android网络请求库中,Retrofit是当下最热的一个网络请求库 今天,我将献上一份非常详细Retrofit v2.0的使用教程,希望你们会 ...

  4. 这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)

    前言 在Andrroid开发中,网络请求十分常用 而在Android网络请求库中,Retrofit是当下最热的一个网络请求库 今天,我将献上一份非常详细Retrofit v2.0的使用教程,希望你们会 ...

  5. 实例讲解Springboot以Repository方式整合Redis

    1 简介 Redis是高性能的NoSQL数据库,经常作为缓存流行于各大互联网架构中.本文将介绍如何在Springboot中整合Spring Data Redis,使用Repository的方式操作. ...

  6. S3C2440上RTC时钟驱动开发实例讲解(转载)

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...

  7. 基于tcpdump实例讲解TCP/IP协议

    前言 虽然网络编程的socket大家很多都会操作,但是很多还是不熟悉socket编程中,底层TCP/IP协议的交互过程,本文会一个简单的客户端程序和服务端程序的交互过程,使用tcpdump抓包,实例讲 ...

  8. 实例讲解基于 React+Redux 的前端开发流程

    原文地址:https://segmentfault.com/a/1190000005356568 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 s ...

  9. TCP入门与实例讲解

    内容简介 TCP是TCP/IP协议栈的核心组成之一,对开发者来说,学习.掌握TCP非常重要. 本文主要内容包括:什么是TCP,为什么要学习TCP,TCP协议格式,通过实例讲解TCP的生命周期(建立连接 ...

随机推荐

  1. 最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目

    最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目 最近一个来自重庆的客户找到走起君,客户的业务是做移动互联网支付,是微信支付收单渠道合作伙伴,数据库里存储的是支付流水和交易流水 ...

  2. 浅谈WEB页面提速(前端向)

    记得面试现在这份工作的时候,一位领导语重心长地谈道——当今的世界是互联网的世界,IT企业之间的竞争是很激烈的,如果一个网页的加载和显示速度,相比别人的站点页面有那么0.1秒的提升,那也是很大的一个成就 ...

  3. EntityFramework之DetectChanges's Secrets(三)(我为EF正名)

    前言 对于应用程序开发者来说,通常不需要考虑太多对于Entity Framework中的变更追踪(change tracking),但是变更追踪和DetectChanges方法是栈的一部分,在这其中, ...

  4. webapi - 模型验证

    本次要和大家分享的是webapi的模型验证,讲解的内容可能不单单是做验证,但都是围绕模型来说明的:首先来吐槽下,今天下午老板为自己买了套新办公家具,看起来挺好说明老板有钱,不好的是我们干技术的又成了搬 ...

  5. 更愉快的书写CSS

    我在写CSS的时候经常会碰到些麻烦事儿: 1)看上去蛮简单的排版却写了很久 2)代码写的越来越散,总是这里补一句,那里补一句,没有条理性 3)margin.padding.font-size等属性在不 ...

  6. 邮件中嵌入html中要注意的样式

    工作中常会有需求向用户发送邮件,需要前端工程师来制作html格式的邮件,但是由于邮件客户端对样式的支持有限,要兼容很多种浏览器需要注意很多原则: 1.邮件使用table+css布局 2.邮件主要部分在 ...

  7. 从史上八大MySQL事故中学到的经验

    本文列举了史上八大MySQL宕机事件原因.影响以及人们从中学到的经验,文中用地震级数来类比宕机事件的严重性和后果,排在最严重层级前两位的是由于亚马逊AWS宕机故障(相当于地震十级和九级). 一.Per ...

  8. Membership三步曲之进阶篇 - 深入剖析Provider Model

    Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...

  9. 最牛的打字效果JS插件 typing.js

    最新在做公司的一个项目,需要实现一个敲打代码的动画效果,粗意味比较简单,果断自己直接开写,写着写着发现是一个坑.需要支持语法高亮,并不能直接简单的用setTimeout来动态附件innerHTML.苦 ...

  10. 【初探Spring】------Spring IOC(一)

    IOC:Inversion of Control(控制反转).IOC它所体现的并不是一种技术,而是一种思想,一种将设计好的对象交给容器来管理的思想.IOC的核心思想就体现在控制.反转这两个词上面,要理 ...