mirror of
https://github.com/wahyd4/libr-android.git
synced 2026-08-09 04:56:19 +10:00
Add book model
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.github.hoverruan.libr" android:versionCode="1" android:versionName="1.0-SNAPSHOT">
|
||||
package="com.github.hoverruan.libr.mobile" android:versionCode="1" android:versionName="1.0-SNAPSHOT">
|
||||
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.Holo">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity android:name=".ui.MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
|
||||
@@ -19,11 +19,22 @@
|
||||
<version>${platform.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.android</groupId>
|
||||
<artifactId>support-v4</artifactId>
|
||||
<version>r7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.2.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+2
-2
@@ -7,10 +7,10 @@
|
||||
<Button
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/fetchBooksInfo"
|
||||
android:text="@string/fetch_books_info"
|
||||
android:id="@+id/button"/>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/responseContent" android:layout_gravity="left|center_vertical"/>
|
||||
android:id="@+id/response_content" android:layout_gravity="left|center_vertical"/>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Libr Client</string>
|
||||
<string name="fetchBooksInfo">Get books info</string>
|
||||
<string name="fetch_books_info">Get books info</string>
|
||||
<string name="failed_download">Failed to download content</string>
|
||||
<string name="failed_not_connected">No available connection</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
package com.github.hoverruan.libr;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
public static final String LIBR = "LIBR";
|
||||
|
||||
private TextView responseContentView;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.main);
|
||||
|
||||
responseContentView = (TextView) findViewById(R.id.responseContent);
|
||||
|
||||
Button button = (Button) findViewById(R.id.button);
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
if (!isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
new DownloadBooksInfo().execute("http://libr.herokuapp.com/api/books");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isConnected() {
|
||||
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
|
||||
|
||||
return networkInfo != null && networkInfo.isConnected();
|
||||
}
|
||||
|
||||
private class DownloadBooksInfo extends AsyncTask<String, Void, String> {
|
||||
|
||||
protected String doInBackground(String... urls) {
|
||||
try {
|
||||
return downloadFromUrl(urls[0]);
|
||||
} catch (IOException e) {
|
||||
Log.e(LIBR, "Unable to retrieve books info");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String downloadFromUrl(String myurl) throws IOException {
|
||||
InputStream is = null;
|
||||
// Only display the first 500 characters of the retrieved
|
||||
// web page content.
|
||||
int len = 500;
|
||||
|
||||
try {
|
||||
URL url = new URL(myurl);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setReadTimeout(10000 /* milliseconds */);
|
||||
conn.setConnectTimeout(15000 /* milliseconds */);
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setDoInput(true);
|
||||
// Starts the query
|
||||
conn.connect();
|
||||
int response = conn.getResponseCode();
|
||||
Log.d(LIBR, "The response is: " + response);
|
||||
is = conn.getInputStream();
|
||||
|
||||
// Convert the InputStream into a string
|
||||
return readIt(is, len);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String readIt(InputStream stream, int len) throws IOException {
|
||||
Reader reader = new InputStreamReader(stream, "UTF-8");
|
||||
char[] buffer = new char[len];
|
||||
reader.read(buffer);
|
||||
return new String(buffer);
|
||||
}
|
||||
|
||||
protected void onPostExecute(String booksInfoText) {
|
||||
responseContentView.setText(booksInfoText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.hoverruan.libr.mobile;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class LibrConstants {
|
||||
public static final String TAG = "Libr";
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.github.hoverruan.libr.mobile.domain;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class Book {
|
||||
private long id;
|
||||
private User author;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
private String image;
|
||||
private String isbn;
|
||||
private String name;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public User getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(User author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(Date updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public String getIsbn() {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public void setIsbn(String isbn) {
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.github.hoverruan.libr.mobile.domain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class BookList {
|
||||
private List<Book> books;
|
||||
private int currentPage;
|
||||
private int totalPage;
|
||||
private int totalCount;
|
||||
|
||||
public List<Book> getBooks() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void setBooks(List<Book> books) {
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
public int getCurrentPage() {
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
public void setCurrentPage(int currentPage) {
|
||||
this.currentPage = currentPage;
|
||||
}
|
||||
|
||||
public int getTotalPage() {
|
||||
return totalPage;
|
||||
}
|
||||
|
||||
public void setTotalPage(int totalPage) {
|
||||
this.totalPage = totalPage;
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
public void setTotalCount(int totalCount) {
|
||||
this.totalCount = totalCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.hoverruan.libr.mobile.domain;
|
||||
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class BookParser {
|
||||
public BookList parseBookList(String json) {
|
||||
GsonBuilder builder = new GsonBuilder();
|
||||
builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
|
||||
builder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
Gson gson = builder.create();
|
||||
|
||||
return gson.fromJson(json, BookList.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.github.hoverruan.libr.mobile.domain;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class User {
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.github.hoverruan.libr.mobile.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import com.github.hoverruan.libr.mobile.R;
|
||||
import com.github.hoverruan.libr.mobile.domain.Book;
|
||||
import com.github.hoverruan.libr.mobile.domain.BookList;
|
||||
import com.github.hoverruan.libr.mobile.domain.BookParser;
|
||||
import com.github.hoverruan.libr.mobile.util.DownloadTask;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
private TextView responseContentView;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.main);
|
||||
|
||||
responseContentView = (TextView) findViewById(R.id.response_content);
|
||||
|
||||
Button button = (Button) findViewById(R.id.button);
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
new DownloadBooksInfo().execute("http://libr.herokuapp.com/api/books");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class DownloadBooksInfo extends DownloadTask {
|
||||
private DownloadBooksInfo() {
|
||||
super(MainActivity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String booksInfoText) {
|
||||
if (booksInfoText != null) {
|
||||
BookList bookList = new BookParser().parseBookList(booksInfoText);
|
||||
responseContentView.setText(String.format("Got %d books:\n%s", bookList.getTotalCount(),
|
||||
getAllBooksName(bookList.getBooks())));
|
||||
}
|
||||
}
|
||||
|
||||
private String getAllBooksName(List<Book> books) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Book book : books) {
|
||||
buf.append(book.getName()).append('\n');
|
||||
}
|
||||
buf.append("...\n");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.github.hoverruan.libr.mobile.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import com.github.hoverruan.libr.mobile.LibrConstants;
|
||||
import static com.github.hoverruan.libr.mobile.LibrConstants.TAG;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class DownloadTask extends AsyncTask<String, Void, String> {
|
||||
|
||||
private Context context;
|
||||
|
||||
public DownloadTask(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected String doInBackground(String... urls) {
|
||||
if (!isConnected()) {
|
||||
Log.w(LibrConstants.TAG, "No available connection");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return downloadFromUrl(urls[0]);
|
||||
} catch (IOException e) {
|
||||
Log.e(LibrConstants.TAG, "Failed to download content");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String downloadFromUrl(String resourceUrl) throws IOException {
|
||||
InputStream is = null;
|
||||
|
||||
try {
|
||||
URL url = new URL(resourceUrl);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setReadTimeout(10000 /* milliseconds */);
|
||||
conn.setConnectTimeout(15000 /* milliseconds */);
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setDoInput(true);
|
||||
// Starts the query
|
||||
conn.connect();
|
||||
int response = conn.getResponseCode();
|
||||
Log.d(TAG, "The response is: " + response);
|
||||
is = conn.getInputStream();
|
||||
|
||||
// Convert the InputStream into a string
|
||||
return readIt(is);
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String readIt(InputStream stream) throws IOException {
|
||||
Reader reader = new InputStreamReader(stream, "UTF-8");
|
||||
char[] buffer = new char[1024];
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int len;
|
||||
while ((len = reader.read(buffer)) > 0) {
|
||||
builder.append(buffer, 0, len);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private boolean isConnected() {
|
||||
ConnectivityManager connectivityManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
|
||||
|
||||
return networkInfo != null && networkInfo.isConnected();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.github.hoverruan.libr.mobile.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class ToastUtils {
|
||||
|
||||
public static void show(final Context context, final String message) {
|
||||
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
|
||||
public static void show(final Context context, final int resId) {
|
||||
if (context == null)
|
||||
return;
|
||||
|
||||
show(context, context.getString(resId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.github.hoverruan.libr.mobile.domain;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Hover Ruan
|
||||
*/
|
||||
public class BookParserTest {
|
||||
|
||||
private BookParser bookParser;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
bookParser = new BookParser();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_parse_BookList_from_JSON() throws Exception {
|
||||
String content = readResource("/com/github/hoverruan/libr/mobile/domain/books.json");
|
||||
BookList bookList = bookParser.parseBookList(content);
|
||||
|
||||
assertThat(bookList, is(notNullValue()));
|
||||
assertThat(bookList.getCurrentPage(), is(1));
|
||||
assertThat(bookList.getTotalPage(), is(11));
|
||||
assertThat(bookList.getTotalCount(), is(106));
|
||||
|
||||
List<Book> books = bookList.getBooks();
|
||||
assertThat(books.size(), is(10));
|
||||
|
||||
Book firstBook = books.get(0);
|
||||
assertThat(firstBook.getAuthor(), is(nullValue()));
|
||||
assertThat(firstBook.getCreatedAt(), is(notNullValue()));
|
||||
assertThat(firstBook.getUpdatedAt(), is(notNullValue()));
|
||||
assertThat(firstBook.getName(), is("金矿"));
|
||||
assertThat(firstBook.getId(), is(26L));
|
||||
assertThat(firstBook.getIsbn(), is("9787111316657"));
|
||||
assertThat(firstBook.getImage(), is("http://img3.douban.com/mpic/s4483293.jpg"));
|
||||
}
|
||||
|
||||
protected String readResource(String path) throws Exception {
|
||||
BufferedReader reader = null;
|
||||
StringWriter result;
|
||||
try {
|
||||
InputStream inputStream = getClass().getResourceAsStream(path);
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
|
||||
|
||||
result = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(result);
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
out.println(line);
|
||||
}
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{"books": [
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:33:20+08:00",
|
||||
"id": 26,
|
||||
"image": "http://img3.douban.com/mpic/s4483293.jpg",
|
||||
"isbn": "9787111316657",
|
||||
"name": "\u91d1\u77ff",
|
||||
"updated_at": "2013-02-06T16:33:20+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:34:01+08:00",
|
||||
"id": 27,
|
||||
"image": "http://img3.douban.com/mpic/s5822197.jpg",
|
||||
"isbn": "9787506021395",
|
||||
"name": "\u4e30\u7530\u73b0\u573a\u7ba1\u7406\u65b9\u5f0f",
|
||||
"updated_at": "2013-02-06T16:34:01+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:34:30+08:00",
|
||||
"id": 28,
|
||||
"image": "http://img3.douban.com/mpic/s5779456.jpg",
|
||||
"isbn": "9787500590842",
|
||||
"name": "\u4e30\u7530\u6c7d\u8f66\u7cbe\u76ca\u6a21\u5f0f\u7684\u5b9e\u8df5",
|
||||
"updated_at": "2013-02-06T16:34:30+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:34:39+08:00",
|
||||
"id": 29,
|
||||
"image": "http://img3.douban.com/mpic/s4655120.jpg",
|
||||
"isbn": "9787111330134",
|
||||
"name": "\u4e30\u7530\u6a21\u5f0f",
|
||||
"updated_at": "2013-02-06T16:34:39+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:34:52+08:00",
|
||||
"id": 30,
|
||||
"image": "http://img3.douban.com/mpic/s8855346.jpg",
|
||||
"isbn": "9787111357933",
|
||||
"name": "\u4f1a\u601d\u8003\u7684\u4e30\u7530\u73b0\u573a",
|
||||
"updated_at": "2013-02-06T16:34:52+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:35:07+08:00",
|
||||
"id": 31,
|
||||
"image": "http://img3.douban.com/mpic/s21572450.jpg",
|
||||
"isbn": "9787506049856",
|
||||
"name": "\u4e30\u7530\u73b0\u573a\u7684\u4eba\u624d\u57f9\u80b2",
|
||||
"updated_at": "2013-02-06T16:35:07+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:35:31+08:00",
|
||||
"id": 32,
|
||||
"image": "http://img3.douban.com/mpic/s1222816.jpg",
|
||||
"isbn": "9787532734191",
|
||||
"name": "\u6d77\u8fb9\u7684\u5361\u592b\u5361",
|
||||
"updated_at": "2013-02-06T16:35:31+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:36:10+08:00",
|
||||
"id": 33,
|
||||
"image": "http://img3.douban.com/mpic/s4130817.jpg",
|
||||
"isbn": "9787115218858",
|
||||
"name": "\u8f6f\u4ef6\u8c03\u8bd5\u5b9e\u6218",
|
||||
"updated_at": "2013-02-06T16:36:10+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:36:24+08:00",
|
||||
"id": 34,
|
||||
"image": "http://img3.douban.com/mpic/s6883275.jpg",
|
||||
"isbn": "9787115259653",
|
||||
"name": "\u8f6f\u4ef6\u9879\u76ee\u6210\u529f\u4e4b\u9053",
|
||||
"updated_at": "2013-02-06T16:36:24+08:00"
|
||||
},
|
||||
{
|
||||
"author": null,
|
||||
"created_at": "2013-02-06T16:36:39+08:00",
|
||||
"id": 35,
|
||||
"image": "http://img3.douban.com/mpic/s4409220.jpg",
|
||||
"isbn": "9787111301936",
|
||||
"name": "\u8f6f\u4ef6\u9879\u76ee\u7ba1\u7406\u4e0e\u654f\u6377\u65b9\u6cd5",
|
||||
"updated_at": "2013-02-06T16:36:39+08:00"
|
||||
}
|
||||
], "current_page": "1", "total_page": 11, "total_count": 106}
|
||||
Reference in New Issue
Block a user