用了一个礼拜的时间研究了android连接服务器的大体流程。连接服务器有两种办法,一种是使用java类HttpURLConnection,另一个是使用apache的类HttpClient,看了android的官方文档,在安卓2.3以后建议使用HttpURLConnection进行开发。以下为本人亲测实例,希望对大家有帮助,也作为以后再次使用网络连接服务器的一个参考,如有不对之处,尽请指正,感激不尽。
android客户端: 首先书写一个HttpUtil类,封装了连接、请求服务器所需的post方法和get方法,因为get方法代码比较简单,在此就略过了,代码如下:
public class HttpUtil {
public static final String BASE_URL = "http://xxx.xxx.xxx.xxx:8080/TestAndroidServlet/android/";
public static HttpURLConnection conn;
public static String PostFromWebByHttpURLConnection(String strUrl,
Map<String, String> map) {
String result = "";
try {
URL url = new URL(strUrl);
conn = (HttpURLConnection) url.openConnection();
// 设置是否从httpUrlConnection读入,默认情况下是true;
conn.setDoInput(true);
// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true, 默认情况下是false;
conn.setDoOutput(true);
// 设定请求的方法为"POST",默认是GET
conn.setRequestMethod("POST");
// 设置超时
conn.setConnectTimeout(3000);
conn.setReadTimeout(4000);
// Post 请求不能使用缓存
conn.setUseCaches(false);
// 是否连接遵循重定向
conn.setInstanceFollowRedirects(true);
// 设定传送的内容类型是可序列化的java对象
// (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
// 连接,从上述第2条中url.openConnection()至此的配置必须要在connect之前完成,
conn.connect();
String user = map.get("user");
DataOutputStream dop = new DataOutputStream(conn.getOutputStream());
//用此方法向服务器端发送数据
dop.writeBytes("user="+URLEncoder.encode(user, "utf-8"));
dop.flush();
dop.close();
//接收数据
InputStream in = conn.getInputStream();
InputStreamReader inStream = new InputStreamReader(in);
BufferedReader buffer = new BufferedReader(inStream);
String strLine = null;
while ((strLine = buffer.readLine()) != null) {
result += strLine;
}
return result;
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
}
}
不要忘记给app添加访问网络的权限
<uses-permission android:name="android.permission.INTERNET"/>
主界面程序:
public class Login extends Activity
{
// 定义界面中文本框
EditText etName;
// 定义界面中按钮
Button bnLogin;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
// 获取界面中编辑框
etName = (EditText) findViewById(R.id.userEditText);
// 获取界面中的按钮
bnLogin = (Button) findViewById(R.id.bnLogin);
bnLogin.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// 如果登录成功
if (login())
{
Toast.makeText(Login.this, "连接服务器成功", Toast.LENGTH_LONG).show(); }
}
});
}
private boolean login()
{
// 获取用户输入的用户名 String username = etName.getText().toString();
String result;
try
{
result = query(username);
if ("成功".equals(result.trim()))
{
return true;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
// 定义发送请求的方法
private String query(String username) throws Exception
{
// 使用Map封装请求参数
Map<String, String> map = new HashMap<String, String>();
map.put("user", username);
// 定义发送请求的URL
String url = HttpUtil.BASE_URL + "login.jsp";
// 发送请求
return HttpUtil.PostFromWebByHttpURLConnection(url, map);
}
}
xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1">
<TableRow>
<TextView
android:text="@string/user_name"
android:id="@+id/TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/userEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
/>
</TableRow>
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
>
<Button
android:id="@+id/bnLogin"
android:text="@string/login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</TableLayout>
捎带也把服务器端的代码也写上,使用serlvet3.0的新特性,以注释的方式引入jsp,同时不要忘记引入servlet-api.jar。
最近希望能与struts2进行一下结合,我的设想是用struts2可以使服务器端的开发既能接收到jsp页面的请求,也可以接收到android端的请求,但问题出现在struts2的action中,如果在action中通过ServletActionContext.getRequest()和ServletActionContext.getResponse()获取request对象和response对象的话是没有问题的,但是在往android端使用输入输出流的时候会报错,原因是action会自动生成这个两个对象,并在action中的return的时候调用输出流,这样就导致重复调用输出流,所以解决办法可以设置:return null,这样解决了android端的问题,但是无法把经action处理的值传给jsp了,也就使struts2失去了它原有的优势,也就没有必要再使用struts2了。@WebServlet(urlPatterns = "/android/login.jsp") public class LoginServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String user = request.getParameter("user"); System.out.println(user); response.setContentType("text/html; charset=utf-8"); // 登录成功 if (user.equals("user")) { response.getWriter().println("成功"); } } }
综上,如果你的服务器端需要有jsp页面,同时还要能够处理来自android客户端的请求,那么最好是用struts2处理jsp,用servlet处理android端的请求,这样两不耽误,希望更多使用struts2框架的朋友可以受益,不要再纠结了。