美文网首页
让SpringMVC接收JSON——WebServer(Spri

让SpringMVC接收JSON——WebServer(Spri

作者: hhp895 | 来源:发表于2017-10-04 22:05 被阅读0次

    目标:

    (1)架设可以接收JSON的SpringMVC服务器
    (2)使用Android客户端向服务器发送JSON字符串

    使用SpringMVC+fastjson框架接收JSON字符串

    1. 这里使用阿里的fastjson

    与同类其他json解析框架(jackson、gson)比,其在性能速度上有比较明显的优势。其主要功能是convert Java Objects to JSON String和convert JSON String to Java Objects。
    官方网址:https://github.com/alibaba/fastjson

    1.1 fastjson优势:
    • 提供服务器端和android客户端最好的性能
    • 提供最简单的JSONString()和parseObject()方法去转换Java Objects为JSON,反之亦然
    • 允许先前存在的不能修改的对象转成JSON,以及从JSON转成Object
    • 支持Java 泛型
    • 允许自定义对象的呈现方式
    • 支持复杂对象(继承层次多且大量使用泛型的)
    1.2 使用fastjson:

    Maven 坐标:

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.38</version>
    </dependency>
    

    spring的bean配置:

    <bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig">
            <!-- 自定义配置... -->
            <!-- Default charset -->
            <property name="charset" value="UTF-8" />
            <!-- Default dateFormat -->
            <property name="dateFormat" value="yyyy-MM-dd HH:mm:ss" />
            <!-- SerializerFeature -->
            <property name="serializerFeatures">
                <list>
                    <value>WriteNullListAsEmpty</value>
                </list>
            </property>
      </bean>
      <mvc:annotation-driven>
            <mvc:message-converters register-defaults="true">
                <bean
                    class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>application/json</value>
                        </list>
                    </property>
                    <property name="fastJsonConfig" ref="fastJsonConfig" />
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
    

    这是fastjson在spring4中的配置,与spring3不同,在 <mvc:annotation-driven>中设置message-converters为FastJsonHttpMessageConverter,表示JSON转换器设置为fastjson转换器。supportedMediaTypes表示request数据类型为json类型。fastJsonConfig表示FastJsonHttpMessageConverter的配置。
    其中dateFormat表示date类型字段输出的格式,如果不添加该设置,输出日期值为一个整型数据。
    charset表示response数据类型为utf-8。

    1.3 Controller中如何使用:

    在Controller部分使用@RestController注解,表示输出数据支持字符串

        @RequestMapping(value="")
        public ResultMessage user(){
            return  new ResultMessage("200","成功!",userService.get(1));
        }
    

    当请求该url时,则返回JSON字符串。其中类到JSON的映射是由fastjson完成的。
    JSON字符串如下:

    {
        "code": "200",
        "data": {
            "alias": "张三",
            "id": 1,
            "name": "test",
            "password": "1",
            "reg_date": "2017-10-01 00:00:01",
            "state": 1,
            "type_id": 1
        },
        "msg": "成功!"
    }
    

    可见fastjson支持复杂类对象。

    1.4 接收JSON请求数据

        @RequestMapping(value="",method=RequestMethod.POST,consumes = "application/json",produces={"application/json"})
        public ResultMessage user(@RequestBody User user){
            System.out.println(user);
            return  new ResultMessage("200","成功!",user);
        }
    

    其中@RequestBody表示请求中包含JSON字符串数据,映射到当前user变量上,user类型为User实体。这里fastjson将请求数据自动转换成User类型实例,注入到当前方法中。
    在测试请求时,使用postman工具。需要设置:

    • 设置请求的header部分content-type为application/json


      设置请求的Header
    • 为了发送JSON字符串,设置Body部分,数据类型为raw,并设定数据为:
    设置请求的Body
    • 发送请求后,得到:
    发送JSON,收到JSON

    2 在Android客户端中使用OkHttp向服务器发送JSON请求

    2.1 OkHttp简介

    官网:https://github.com/square/okhttp
    https://square.github.io/okhttp/
    OkHttp是一个支持http协议的客户端,也是一个高效的客户端。特点如下:
    (1)支持HTTP1和2,允许多个针对相同主机的请求共享一个socket。
    (2)使用连接池减少潜在的请求
    (3)Transparent GZIP减少下载大小
    (4)使用响应端缓存避免重复请求。
    Gradle 坐标:

    compile 'com.squareup.okhttp3:okhttp:3.9.0'
    

    2.2 同步请求和异步请求

    (1)同步请求

            OkHttpClient client=new OkHttpClient();
            MediaType JSON=MediaType.parse("application/json; charset=utf-8");
            RequestBody requestBody=RequestBody.create(JSON,jsonValue);
            Request request=new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();
            try {
                Response response=client.newCall(request).execute();
                if(response.isSuccessful()){
                    callback.onResponse(response);
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            }
    

    其中client是请求的客户端。JSON表示请求的数据类型。jsonValue表示请求的json字符串,例如:

     String json ="{\n" +
                                    "\"alias\": \"张三***\",\n" +
                                    "\"id\": 1,\n" +
                                    "\"name\": \"test\",\n" +
                                    "\"password\": \"1\",\n" +
                                    "\"reg_date\": \"2017-10-01 00:00:01\",\n" +
                                    "\"state\": 1,\n" +
                                    "\"type_id\": 1\n" +
                                    "}";
    

    requestBody表示使用json字符串创建的请求数据体,然后使用requestBody初始化一个request。url是一个服务器请求的网址,类型为字符串,再使用client.newCall(request).execute()执行请求,这是一个同步请求。使用response.isSuccessful()判断请求是否得到正确回应。

    注意:由于是同步请求OkHttp并没有提供线程去执行这个网络请求,需要将上述代码放到Thread中去执行。

    (2)异步请求

    try {
                client.newCall(request)
                        .enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                e.printStackTrace();
                            }
    
                            @Override
                            public void onResponse(Call call, final Response response) throws IOException {
    
                             handler.post(new Runnable() {
                                 @Override
                                 public void run() {
                                     if(callback!=null)
                                         callback.onResponse(response);
                                 }
                             });
    
                            }
                        });
            } catch (Exception e) {
                e.printStackTrace();
            }
    

    request的创建过程同“同步请求”代码。不同的是异步请求使用client.newCall(request).enqueue(new Callback(){})。其中enqueue表示这个请求将进入一个队列中。逐个去执行,使用回调方法来做请求响应。onFailure表示请求失败时响应的事件方法。onResponse表示请求有响应时执行的事件方法,其中注入了response可以用于获取响应结果。

    注意:OkHttp已经将异步代码封装到线程中执行,这里在执行异步请求时,无需在线程中执行。

    2.3 进一步封装OkHttp

    public class UtilHttp {
        private static  OkHttpClient client=new OkHttpClient();
        private static Handler handler = new Handler(Looper.getMainLooper());
    
        public static final MediaType JSON=MediaType.parse("application/json; charset=utf-8");
        public static void execute(String url, String jsonKey, 
                                   String jsonValue, 
                                   final ResponseCallback callback){
    
            RequestBody requestBody=RequestBody.create(JSON,jsonValue);
    
            Request request=new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();
            try {
                client.newCall(request)
                        .enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                e.printStackTrace();
                            }
    
                            @Override
                            public void onResponse(Call call, 
                                                   final Response response) throws IOException {
    
                             handler.post(new Runnable() {
                                 @Override
                                 public void run() {
                                     if(callback!=null)
                                         callback.onResponse(response);
                                 }
                             });
    
                            }
                        });
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    //        try {
    //            Response response=client.newCall(request).execute();
    //            if(response.isSuccessful()){
    //                callback.onResponse(response);
    //            }
    //        } catch (IOException e) {
    //            e.printStackTrace();
    //        }
        }
        public  interface ResponseCallback{
            void onResponse(Response response);
        }
    }
    

    其中new Handler(Looper.getMainLooper())表示获取主线程的Handler,用于网络响应后直接进行UI操作,也可以不用在Activity中再次实例化Handler。
    定义接口ResponseCallback实现回调方法的封装,方便Activity传递回调方法实例。 handler.post(new Runnable() {})表示handler直接操作UI控件。所以ResponseCallback的回调方法中可以直接操作Acitivity中的UI。

       String json ="{\n" +
                    "\"alias\": \"张三***\",\n" +
                    "\"id\": 1,\n" +
                    "\"name\": \"test\",\n" +
                    "\"password\": \"1\",\n" +
                    "\"reg_date\": \"2017-10-01 00:00:01\",\n" +
                    "\"state\": 1,\n" +
                    "\"type_id\": 1\n" +
                    "}";
    
            UtilHttp.execute(url, "user", json,  new UtilHttp.ResponseCallback() {
                @Override
                public void onResponse(Response response) {
    
                    String msg= null;
                    try {
                        msg = response.body().string();
    //                                    Log.i("TAG",msg);
                        Toast.makeText(MainActivity.this,msg,Toast.LENGTH_LONG).show();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                }
            });
    

    点击按钮,执行效果如:

    发送JSON,收到JSON

    相关文章

      网友评论

          本文标题:让SpringMVC接收JSON——WebServer(Spri

          本文链接:https://www.haomeiwen.com/subject/ipmcyxtx.html