REST描述的是在网络中客户端和服务端的一种交互形式
(Resource) REpresentational State Transfer 直译为 资源的表现层状态转移
1.Resource:资源,即数据。比如 friends等
(1)http://api.qc.com/v1/friends: 获取某人的好友列表;
(2)http://api.qc.com/v1/profile: 获取某人的详细信息
2.Representational:某种表现形式,比如用JSON,XML,JPEG等;
3.State Transfer:状态变化。通过HTTP动词实现(如Get、Post)。
要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI(Uniform Resource Identifier)。
URI既可以看成是资源的地址,也可以看成是资源的名称。
URI的设计应该遵循可寻址性原则,具有自描述性,需要在形式上给人以直觉上的关联。
使用/来表示资源的层级关系,使用?用来过滤资源(理解成筛选资源)
GET 用来获取资源
POST 用来新建资源(也可以用于更新资源)
PUT 用来更新资源
DELETE 用来删除资源
get请求会将请求参数拼接到url后面
post请求的参数会放到body里面(好处是参数长度不受限制)
文本资源可以采用html、xml、json等格式,图片可以使用PNG或JPG展现出来。
可扩展标记语言(Extensible Markup Language,简称:XML)是一种标记语言。
标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。
特点:以某个结点开始,再以某个结点结束
可以通过以下网址格式化JSON,以及,判断字符串是不是正确得JSON https://www.bejson.com/
键值对的值一定是以下6个类型之一
❏ JSON strings { “name”:“John” }
❏ JSON Numbers, integer or float { “age”:30 }
❏ JSON Objects {“employee”:{ “name”:“John”, “age”:30, “city”:“New York” }}
❏ JSON Arrays {“employees”:[ “John”, “Anna”, “Peter” ]}
❏ JSON Booleans { “sale”:true }
❏ JSON null { “middlename”:null }
注意:中括号表示数组,大括号表示对象
分为两步
public static void generateJsonString() {
try {
JSONObject jsonObject = new JSONObject();
JSONObject tempJson = new JSONObject();
tempJson.put("min", 11.34);
tempJson.put("max", 19.01);
jsonObject.put("temp", tempJson);
JSONObject weatherJSON = new JSONObject();
weatherJSON.put("id",801);
weatherJSON.put("condition","Clouds");
weatherJSON.put("description",null);
jsonObject.put("weather",weatherJSON);
jsonObject.put("success", true);
JSONArray jsonArray = new JSONArray();
jsonArray.put("Adam");
jsonArray.put("Bob");
jsonArray.put("John");
jsonObject.put("notification_user_id", jsonArray);
Log.d("JsonDemo", jsonObject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
public static void parseJsonString() {
String s = "{\"temp\":{\"min\":11.34,\"max\":19.01},\"success\":true,\"notification_user_id\":[\"Adam\",\"Bob\",\"John\"]}";
//可以通过www.bejson.com/ “压缩并转义”得到
try {
JSONObject jsonObject = new JSONObject(s);//要把字符串传进来
JSONObject temp = jsonObject.getJSONObject("temp");
double min = temp.getDouble("min");
double max = temp.getDouble("max");
JSONArray notificationUserId = jsonObject.getJSONArray("notification_user_id");
ArrayList<String> strings = new ArrayList<>();//JSONArray和ArrayList<String>不同
for (int i = 0; i < notificationUserId.length(); i++) {
strings.add(notificationUserId.getString(i));
}
boolean success = jsonObject.optBoolean("success");
boolean unexist = jsonObject.optBoolean("unexist",true);//返回默认值true
Log.d("JsonDemo", "success:" + unexist);
} catch (JSONException e) {
Log.d("JsonDemo", "crash:"+e.getMessage());
e.printStackTrace();
}
}
小结:opt方法在没有对应值的时候可以返回一个默认值,而get方法会报错
在解析复杂数据和生成复杂字符串时方便很多,可以直接把一个类转化成JSON
首先要在build.gradle的依赖里面加入
implementation 'com.google.code.gson:gson:2.8.6'
例如,想建立People这个类的JSON
public class People{
public int age;
public String name;
public People friend;
public List<String> friends;
}
在GsonDemo中
public static void generateGsonString(){
Gson gson = new Gson();
People people = new People();
people.age = 21;
people.name = "yoyo";
People myFriend = new People();
myFriend.age = 21;
myFriend.name = "wyc";
people.friend = myFriend;
ArrayList<String> friends = new ArrayList<>();
friends.add("sss");
friends.add("ddd");
friends.add("nnn");
people.friends = friends;
String s = gson.toJson(people);//直接把一个类转化成JSON
}
反之,如何将一个JSON转化成对象呢,GSON也只用一行代码
①如果是一个对象
public static void parseGsonString(){
String s = "";//这里JSON字符串略
Gson gson = new Gson();
People people = gson.fromJson(s,People.class);//JSON转化成对象
}
注:如果想查看,可以在People类加上toString()方法,就能打印转化出来的对象
②如果是对象的集合
public static void parseGsonString(){
String s = "";//这里JSON字符串略
Gson gson = new Gson();
List<People> peoples = gson.fromJson(s, new TypeToken<List<People>>(){
}.getType());
}
@SerializedName 注解的使用
如果在JSON字符串中的"firstname"属性对应的是People类中的"name"属性
那么可以在People类中
public class People{
public int age;
@SerializedName("firstname")//表示对应要解析的字段
public String name;
public People friend;
public List<String> friends;
}
这样两者就能够对应起来
该注解在生成JSON时也会产生作用
首先,需要在AndroidManifest.xml中配置两个权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
然后在build.gradle的依赖里面加入
implementation "com.squareup.retrofit2:retrofit:2.8.1"
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'//将返回值转换成JSON
定义ApiService接口
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
public interface ApiService {
// https://wanandroid.com/wxarticle/chapters/json
@GET("wxarticle/chapters/json")
Call<ArticleResponse> getArticles(@Query("user") String name);
// todo 添加api
// https://www.wanandroid.com/user/register
//方法:POST
// username,password,repassword
@FormUrlEncoded
@POST("user/register")
Call<UserResponse> register(@Field("username")String username,
@Field("password")String password,
@Field("repassword")String repassword);
}
在MainActivity类里面
private void getData() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://wanandroid.com/")//这是上面那个url的前半截
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService apiService = retrofit.create(ApiService.class);
apiService.getArticles().enqueue(new Callback<ArticleResponse>() {
@Override
public void onResponse(Call<ArticleResponse> call, Response<ArticleResponse> response) {
if (response.body() != null) {
List<ArticleResponse.Article> articles = response.body().articles;
Log.d("retrofit", articles.toString());
if (articles.size() != 0) {
mAdapter.setData(response.body().articles);
mAdapter.notifyDataSetChanged();
}
}
}
@Override
public void onFailure(Call<ArticleResponse> call, Throwable t) {
Log.d("retrofit", t.getMessage());
}
});
}