版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

这一篇主要讲一下将OkHttpUtils运用到mvp模式中。

数据请求地址:http://www.wanandroid.com/tools/mockapi/418/version

效果图

代码分析

1、集成OKHttpUtils开源库参考《okhttputils【 Android 一个改善的okHttp封装库】使用(一)》;

2、使用mvp模式封装网络请求。

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

集成OKHttpUtils

参考《okhttputils【 Android 一个改善的okHttp封装库】使用(一)

mvp模式下修改和新增的类文件

LoginLogic.java【调用的方法需要传入tag值,且注意方法命名规则:xxxApi】

package com.why.project.okhttputilsmvpdemo.logic;

import com.why.project.okhttputilsmvpdemo.MyApplication;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback; /**
* Created by HaiyuKing
* Used
*/ public class LoginLogic extends BaseLogic { private static LoginLogic _Instance = null; public static LoginLogic Instance() {
if (_Instance == null)
_Instance = new LoginLogic();
return _Instance;
}
private LoginLogic() {
this.context = MyApplication.getAppContext();//防止了内存泄漏
} /**
* 发现新版本接口
*/
public String updateVersionApi(String tag, StringCallback callback)
throws Exception {
String result = "";
OkHttpUtils
.get()
.url(getSpcyUrl(ServerApi.UPDATE_VERSION_URL))
.id(100)
.tag(tag)
.build()
.execute(callback);
return result;
}
}

UpdateVersionBean.java【一般项目中都是需要用到的】

package com.why.project.okhttputilsmvpdemo.bean;

/**
* Created by HaiyuKing
* Used 更新APP的实体类
*/ public class UpdateVersionBean { private String versionName;//服务器上的版本号,比如3.0
private String forceUpdate;//是否强制更新
private String title;//标题,如果为空,则默认显示发现新版本
private String content;//更新内容,如果为空,则不显示
private String downloadurl;//下载地址
private String fileSize;//文件大小 public String getVersionName() {
return versionName;
} public void setVersionName(String versionName) {
this.versionName = versionName;
} public String getForceUpdate() {
return forceUpdate;
} public void setForceUpdate(String forceUpdate) {
this.forceUpdate = forceUpdate;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public String getDownloadurl() {
return downloadurl;
} public void setDownloadurl(String downloadurl) {
this.downloadurl = downloadurl;
} public String getFileSize() {
return fileSize;
} public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
}

 UpdateVersionModel.java【命名规则:bean类的前缀+Model】【用于封装网络请求,然后通过callback回调】

package com.why.project.okhttputilsmvpdemo.model;

import android.content.Context;

import com.why.project.okhttputilsmvpdemo.MyApplication;
import com.why.project.okhttputilsmvpdemo.R;
import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
import com.why.project.okhttputilsmvpdemo.logic.LoginLogic;
import com.zhy.http.okhttp.callback.StringCallback; import org.json.JSONException;
import org.json.JSONObject; import okhttp3.Call;
import okhttp3.Request; /**
* Created by HaiyuKing
* Used 发现新版本的请求类
*/ public class UpdateVersionModel { /**获取新版本的信息*/
public void updateVersionInfo(String tag,
final LoadingDataCallBack<UpdateVersionBean> callBack) {
final Context mContext = MyApplication.getAppContext();
//执行请求任务
try {
LoginLogic.Instance().updateVersionApi(tag,new StringCallback() {
@Override
public void onBefore(Request request, int id)
{
callBack.onBefore("");//回调
}
@Override
public void onAfter(int id)
{
callBack.onAfter();//回调
}
@Override
public void onError(Call call, Exception e, int id)
{
callBack.onError("");//回调
}
@Override
public void onResponse(String response, int id)
{
switch (id)
{
case 100://http
try {
if (response != null && !"".equals(response)){
JSONObject versionInfoObj = new JSONObject(response); UpdateVersionBean updateVersionBean = new UpdateVersionBean();
updateVersionBean.setVersionName(versionInfoObj.getString("versionName"));
updateVersionBean.setForceUpdate(versionInfoObj.getString("forceUpdate"));
updateVersionBean.setTitle(versionInfoObj.getString("title"));
updateVersionBean.setContent(versionInfoObj.getString("content"));
updateVersionBean.setDownloadurl(versionInfoObj.getString("downloadurl"));
updateVersionBean.setFileSize(versionInfoObj.getString("fileSize")); callBack.onSuccess(updateVersionBean);
}else {
//提示失败
callBack.onFailure("");//回调
}
}catch (JSONException e) {
callBack.onError(mContext.getResources().getString(R.string.login_json_exception));//回调
}catch (Exception e) {
callBack.onError(mContext.getResources().getString(R.string.login_json_exception));//回调
}
break;
case 101://https
break;
}
}
@Override
public void inProgress(float progress, long total, int id)
{
//callBack.onProgress(progress,total,id);//回调
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

LoadingDataCallBack.java【网路请求的回调】

package com.why.project.okhttputilsmvpdemo.model;

/**
* Used 常规接口请求的回调【请求发现新版本接口】
*/ public interface LoadingDataCallBack<T> { /**
* 数据请求前的操作
* @ TODO 一般用于显示加载对话框
*/
void onBefore(String msg); /**
* 当请求数据结束时,无论请求结果是成功,失败或是抛出异常都会执行此方法给用户做处理
* @ TODO 请求结束,一般隐藏加载提示对话框,或者执行下一步操作
*/
void onAfter(); /**
* 数据请求成功
* @param response 请求到的数据
* @ TODO 请求成功,一般执行下一步的操作(继续请求接口,或者显示)
*/
void onSuccess(T response); /**
* 数据请求成功的提示语
* @param msg 提示语
* @ TODO 请求成功,一般用来提示msg
*/
void onSuccessToast(String msg); /**
* 请求失败
* 使用网络API接口请求方式时,虽然已经请求成功但是由于{@code msg}的原因无法正常返回数据。
* @ TODO 请求失败,一般用来提示msg状态值以及提示语,或者显示无数据的区域【所以需要跟onError方法区别开来】
*/
void onFailure(String msg); /**
* 请求数据错误,指在请求网络API接口请求方式时,出现无法联网、缺少权限,内存泄露等原因导致无法连接到请求数据源。
* @ TODO 请求错误,一般隐藏加载提示对话框,提示服务器返回的失败信息等
*/
void onError(String msg); /**
* 无网络时返回
* @ TODO 一般隐藏加载提示对话框,提示当前网络不可用,或者显示无网络的区域【所以需要跟onError方法区别开来】
*/
void onNoNetWork(String msg);
}

IBaseView.java【提取出来通用的抽象方法】

package com.why.project.okhttputilsmvpdemo.iview;

/**
* Created by HaiyuKing
* Used IView基类接口(含有通用的抽象方法声明)
*/ public interface IBaseView {
/** 显示正在加载进度框【通用】*/
void showLoading(String msg); /** 隐藏正在加载进度框【通用】*/
void hideLoading(); /**显示提示信息【通用】*/
void showToast(String msg); /** 获取OkHttpUtil用到的tag,一般使用当前类的类名即可。比如:this.getClass().getSimpleName()【通用】*/
String getOkHttpUtilTag(); /** 处理失败的情况【应该每一个接口对应一个,不过此处省略了】【主要用于第一次请求的时候,显示提示区域,一般情况下可以直接showToast即可】*/
void showFail(String msg); /**
* 处理无网络的情况【应该每一个接口对应一个,不过此处省略了】【主要用于第一次请求的时候,显示提示区域,一般情况下可以直接showToast即可】*/
void showNotNetWork(String msg);
}

IUpdateAppView.java【如果跟某个activity或者fragment耦合度很高,那么可以命名为MainActivityView.java(也就是以这个activity或者fragment命名)】【命名规则:I{xxx}View】

package com.why.project.okhttputilsmvpdemo.iview;

import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;

/**
* Created by HaiyuKing
* Used 更新APP的view
*/ public interface IUpdateAppView extends IBaseView{ /** 打开发现新版本对话框*/
void showUpdateDialog(UpdateVersionBean updateVersionBean); }

UpdateAppPresenter.java【如果跟某个activity或者fragment耦合度很高,那么可以命名为MainActivityPresenter.java(也就是以这个activity或者fragment命名)】【命名规则:xxxxPresenter】

package com.why.project.okhttputilsmvpdemo.presenter;

import android.text.TextUtils;

import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
import com.why.project.okhttputilsmvpdemo.iview.IUpdateAppView;
import com.why.project.okhttputilsmvpdemo.model.LoadingDataCallBack;
import com.why.project.okhttputilsmvpdemo.model.UpdateVersionModel; /**
* Created by HaiyuKing
* Used 更新APP的presenter
*/ public class UpdateAppPresenter {
private IUpdateAppView mvpView;//view接口类
private UpdateVersionModel mUpdateVersionModel;//发现新版本接口请求的model类 public UpdateAppPresenter(){
mUpdateVersionModel = new UpdateVersionModel();
} /**
* 绑定view,一般在初始化中调用该方法
*/
public void attachView(IUpdateAppView view){
mvpView = view;
} /**
* 断开view,一般在onDestroy中调用
*/
public void detachView() {
mvpView = null;
} /**
* 是否与View建立连接
* 每次调用业务请求的时候都要出先调用方法检查是否与View建立连接
*/
public boolean isViewAttached(){
return mvpView != null;
} /**发现新版本接口数据*/
public void updateVersion() {
if (!TextUtils.isEmpty(mvpView.getOkHttpUtilTag())) {
mUpdateVersionModel.updateVersionInfo(mvpView.getOkHttpUtilTag(),
new LoadingDataCallBack<UpdateVersionBean>() {
@Override
public void onBefore(String msg) {
if (isViewAttached()) {
mvpView.showLoading(msg);
}
} @Override
public void onAfter() {
if (isViewAttached()) {
mvpView.hideLoading();
}
} @Override
public void onSuccess(UpdateVersionBean response) {
if (isViewAttached()) {
mvpView.showUpdateDialog(response);
}
} @Override
public void onSuccessToast(String msg) {
if (isViewAttached()) {
mvpView.showToast(msg);
}
} @Override
public void onFailure(String msg) {
if (isViewAttached()) {
mvpView.showFail(msg);
}
} @Override
public void onError(String msg) {
if (isViewAttached()) {
mvpView.showToast(msg);
}
} @Override
public void onNoNetWork(String msg) { }
});
}
}
}

三、使用方法

Activity下的使用

package com.why.project.okhttputilsmvpdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
import com.why.project.okhttputilsmvpdemo.iview.IUpdateAppView;
import com.why.project.okhttputilsmvpdemo.presenter.UpdateAppPresenter;
import com.why.project.okhttputilsmvpdemo.utils.ToastUtil;
import com.why.project.okhttputilsmvpdemo.utils.httputil.HttpUtil;
import com.zhy.http.okhttp.OkHttpUtils; public class MainActivity extends AppCompatActivity implements IUpdateAppView{ private static final String TAG = MainActivity.class.getSimpleName(); private UpdateAppPresenter mvpUpdateAppPresenter;//发现新版本
private String okHttpTag = "";//网络请求用到的tag private Button btn_get;
private TextView tv_show; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //presenter绑定view{1}
if(mvpUpdateAppPresenter == null){
mvpUpdateAppPresenter = new UpdateAppPresenter();
}
//presenter绑定view{2}
if(mvpUpdateAppPresenter != null) {
mvpUpdateAppPresenter.attachView(this);
} initViews();
initData();
initEvents();
} @Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
//取消网络请求,根据tag取消请求
OkHttpUtils.getInstance().cancelTag(okHttpTag);
} protected void onDestroy() {
//取消网络请求
Log.w(TAG,"this.getClass().getSimpleName()="+this.getClass().getSimpleName());
OkHttpUtils.getInstance().cancelTag(okHttpTag);
super.onDestroy(); //presenter解绑view{3}
if(mvpUpdateAppPresenter != null){
mvpUpdateAppPresenter.detachView();
}
} private void initViews() {
btn_get = (Button) findViewById(R.id.btn_get);
tv_show = (TextView) findViewById(R.id.tv_show);
} /**初始化数据*/
private void initData() {
okHttpTag = this.getClass().getSimpleName();
} private void initEvents() {
btn_get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (HttpUtil.isNetworkAvailable(MainActivity.this)) {
//执行网络请求接口
try {
mvpUpdateAppPresenter.updateVersion();//请求发现新版本接口
} catch (Exception e) {
e.printStackTrace();
}
}else{
ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.network_enable));
}
}
});
} @Override
public void showLoading(String msg) {
//showProgressDialog("");//显示进度加载框
} @Override
public void hideLoading() {
//dismissProgressDialog();//隐藏进度加载框
} @Override
public void showToast(String msg) {
ToastUtil.showShortToast(msg);
} @Override
public String getOkHttpUtilTag() {
return okHttpTag;
} @Override
public void showFail(String msg) {
ToastUtil.showShortToast(msg);
} @Override
public void showNotNetWork(String msg) {
ToastUtil.showShortToast(msg);
} @Override
public void showUpdateDialog(UpdateVersionBean updateVersionBean) {
String showText = "新版本号:" + updateVersionBean.getVersionName() +
"\n是否强制更新:" + updateVersionBean.getForceUpdate() +
"\n标题:" + updateVersionBean.getTitle() +
"\n内容:" + updateVersionBean.getContent().replace("\\n", "\n") +
"\n文件大小:" + updateVersionBean.getFileSize() +
"\n下载地址:" + updateVersionBean.getDownloadurl();
tv_show.setText(showText);
}
}

Fragment下的使用

package com.why.project.okhttputilsmvpdemo;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView; import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
import com.why.project.okhttputilsmvpdemo.iview.IUpdateAppView;
import com.why.project.okhttputilsmvpdemo.presenter.UpdateAppPresenter;
import com.why.project.okhttputilsmvpdemo.utils.ToastUtil;
import com.why.project.okhttputilsmvpdemo.utils.httputil.HttpUtil;
import com.zhy.http.okhttp.OkHttpUtils; /**
* Created by HaiyuKing
* Used
*/ public class MainFragment extends Fragment implements IUpdateAppView{
private static final String TAG = MainFragment.class.getSimpleName(); private UpdateAppPresenter mvpUpdateAppPresenter;//发现新版本
private String okHttpTag = "";//网络请求用到的tag /**View实例*/
private View myView;
private Context mContext; private Button btn_get;
private TextView tv_show; @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//presenter绑定view{1}
if(mvpUpdateAppPresenter == null){
mvpUpdateAppPresenter = new UpdateAppPresenter();
}
} //重写
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//presenter绑定view【适用presenter调用代码在onCreateView方法中执行的情况】{2}
/*if(mvpPresenter != null) {
mvpPresenter.attachView(this);
}*/
myView = inflater.inflate(R.layout.activity_main, container, false);
return myView;
} @Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
//由于fragment生命周期比较复杂,所以Presenter在onCreateView创建视图之后再进行绑定,不然会报空指针异常
//presenter绑定view【如果presenter调用的代码是在onCreateView中执行的话,那么此处不合适执行绑定的方法】{2"}
if(mvpUpdateAppPresenter != null) {
mvpUpdateAppPresenter.attachView(this);
} mContext = getActivity(); //初始化控件以及设置
initViews();
//初始化数据
initData();
initEvents();
} @Override
public void onResume() {
super.onResume();
} @Override
public void onPause() {
super.onPause();
} @Override
public void onDestroyView() {
//presenter解绑view{3}
if(mvpUpdateAppPresenter != null){
mvpUpdateAppPresenter.detachView();
}
super.onDestroyView();
} @Override
public void onDestroy() {
//取消网络请求
OkHttpUtils.getInstance().cancelTag(okHttpTag);
super.onDestroy();
} private void initViews() {
btn_get = (Button) myView.findViewById(R.id.btn_get);
tv_show = (TextView) myView.findViewById(R.id.tv_show);
} /**初始化数据*/
private void initData() {
okHttpTag = this.getClass().getSimpleName();
} private void initEvents() {
btn_get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (HttpUtil.isNetworkAvailable(mContext)) {
//执行网络请求接口
try {
mvpUpdateAppPresenter.updateVersion();//请求发现新版本接口
} catch (Exception e) {
e.printStackTrace();
}
}else{
ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.network_enable));
}
}
});
} @Override
public void showLoading(String msg) {
//showProgressDialog("");//显示进度加载框
} @Override
public void hideLoading() {
//dismissProgressDialog();//隐藏进度加载框
} @Override
public void showToast(String msg) {
ToastUtil.showShortToast(msg);
} @Override
public String getOkHttpUtilTag() {
return okHttpTag;
} @Override
public void showFail(String msg) {
ToastUtil.showShortToast(msg);
} @Override
public void showNotNetWork(String msg) {
ToastUtil.showShortToast(msg);
} @Override
public void showUpdateDialog(UpdateVersionBean updateVersionBean) {
String showText = "新版本号:" + updateVersionBean.getVersionName() +
"\n是否强制更新:" + updateVersionBean.getForceUpdate() +
"\n标题:" + updateVersionBean.getTitle() +
"\n内容:" + updateVersionBean.getContent().replace("\\n", "\n") +
"\n文件大小:" + updateVersionBean.getFileSize() +
"\n下载地址:" + updateVersionBean.getDownloadurl();
tv_show.setText(showText);
}
}

混淆配置

参考《okhttputils【 Android 一个改善的okHttp封装库】使用(一)

参考资料

暂时空缺

项目demo下载地址

https://github.com/haiyuKing/OkHttpUtilsMvpDemo

okhttputils【 Android 一个改善的okHttp封装库】使用(三)的更多相关文章

  1. okhttputils【 Android 一个改善的okHttp封装库】使用(一)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本文使用的OKHttp封装库是张鸿洋(鸿神)写的,因为在项目中一直使用这个库,所以对于一些常用的请求方式都验证过,所以特此整理下. ...

  2. Android 一个改善的okHttp封装库

    膜拜一下~ 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/49734867: 本文出自:[张鸿洋的博客] 一.概述 之前写了篇A ...

  3. okhttputils【 Android 一个改善的okHttp封装库】使用(二)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 上一篇讲了如何在项目中导入OKHttputils库的操作,这一篇主要讲常见请求的写法. get请求 public String getPe ...

  4. Android 一个改进的okHttp封装库

    一.概述 之前写了篇Android OkHttp完全解析 是时候来了解OkHttp了,其实主要是作为okhttp的普及文章,当然里面也简单封装了工具类,没想到关注和使用的人还挺多的,由于这股热情,该工 ...

  5. 一个高性能异步socket封装库的实现思路 (c#)

    前言 socket是软件之间通讯最常用的一种方式.c#实现socket通讯有很多中方法,其中效率最高就是异步通讯. 异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理, ...

  6. Android一个包含表格的图标库

    之前有写过一个图表lib,但是开发的速度,大多很难跟上产品需求变化的脚步,所以修改了下原先的图表库,支持图表下面能整合table显示对应的类目,用曲线替换了折线,支持多曲线的显示,增加了显示的动画,, ...

  7. 打造属于自己的Altium Designer 3D封装库,不需要懂专门的三维设计软件

    看到Andy_2020发的帖子“Altium Designer专题”之后,对Altium Designer的3D功能很感兴趣,着手自己做一个AD的3D封装库.刚开始按照Andy介绍的方法,学了两天So ...

  8. 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选

    毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.i ...

  9. Android 设计模式实战之关于封装计费代码库的策略模式详谈

    写在之前 这周生活上出现了很多的不如意,从周一开始就觉得哪里出现了问题,然后就是各种烦躁的情绪,后来事情还真是如预感的那样发生了,很是心痛,但也无可奈何,希望大家都好好珍惜自己身边的人:友人,亲人,家 ...

随机推荐

  1. selenium webdriver (python)大全

    webdriver的简介 硒2.0的主要新功能是集成的webdriver的API.webdriver的设计除了解决一些seleniumr-RC API的一些限制,与webdriver 的整合,将提供一 ...

  2. GO语言.树莓派.环境安装和测试

    Go是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言.为了方便搜索和识别,有时会将其称为Golang 记录一下如何在树莓派上安装语言环境 第一步: 下载安装包 http ...

  3. election.go

    package)) ].GetResponseRange().Kvs[] ) ].Value),]         }         wch := client.Watch(cctx, string ...

  4. gitlab pipelines job执行时日志较大报错

    问题描述 gitlab pipelines job执行时日志较大报错 Job's log exceeded limit of 4194304 bytes. 解决方案 出现该问题主要是因为gitlab ...

  5. 面试必问!Java 多线程中两个线程交替执行,一个输出偶数,一个输出奇数

    前言 楼主今天在面经上看到这个题,挺有意思,小小的题目对多线程的考量还挺多.大部分同学都会使用 synchronized 来实现.楼主今天带来另外两种优化实现,让你面试的时候,傲视群雄! 第一种 sy ...

  6. h5区块链项目实战

    近来区块链一词很热门,网络上关乎其讨论也很多,这里就不解释了,毕竟几句话也是说不清楚的. 最近得空利用HTML5+css3+jQ开发了一个移动端的区块链项目,感觉界面.布局.效果还是ok的. 项目效果 ...

  7. Map集合中,关于取值和遍历的相关操作

    这是自己的关于map集合的相关操作的小研究,分享给大家. 主要代码内容包含以下: 1,map集合的遍历 2,根据key值获取value值 3,根据value值获取key值 4,返回最大value值对应 ...

  8. 简述RPC原理实现

      前言 架构的改变,往往是因为业务规模的扩张. 随着业务规模的扩张,为了满足业务对技术的要求,技术架构需要从单体应用架构升级到分布式服务架构,来降低公司的技术成本,更好的适应业务的发展. 分布式服务 ...

  9. 干货,一文带你超详细了解Session的原理及应用

    session 简介 session 是我们 jsp 九大隐含对象的一个对象. session 称作域对象,他的作用是保存一些信息,而 session 这个域对象是一次会话期间使用同一个对象.所以这个 ...

  10. 兄弟俩畅游Tomcat城市的SpringMVC科技园区

    Tomcat城市 Tomcat这座城市的历史相当悠久了,经历过几次大的变迁后,呈现出非常明显的地域特征. 从城市往西走,过了城乡结合部以后,可以说是满目疮痍.一片破败,这就是Servlet地区,这座城 ...