1. 与WEB服务器交换数据
1.1 知识点
(1)可以通过地址重写的方式进行Web Server的访问;
(2)可以采用POST方式进行请求的提交;
(3)可以读取网络上的图片信息;
1.2 具体内容
首先我们简单介绍JavaWeb相关知识,JavaWeb开发的项目称为B/S架构,B代表就是浏览器,S代表是服务器,相对我们最早的C/S程序而言,有课长足的进步。目前主流的B/S开发程序设计语言有以下几种:
·Sun :jsp/Servlet JavaWeb\JavaEE,前台使用jsp(Java+javascript+html),后端使用Servlet(使用Java编写)
·微软:asp.net 前端asp(html+vbscript),后端使用C#
·php:早就过时了,但是使用php开发成本低,现在很多沿海地区一些山寨品牌推广还会使用php
·Adobe:Flex (html+actionscript) 后端大部分也是使用Java开发
怎么去开发JSP/ervlet,首先我们要搭建开发平台。
·数据库基本操作:
select * from dh10_student t for update;--表示查询并且可以编辑数据
insert into dh10_student (stu_id,stu_name,stu_age,stu_sex) values (1,'小明',20,1);--插入数据
select t.stu_id,t.stu_name,t.stu_age ,decode(nvl(t.stu_sex,0),0,'女',1,'男') from dh10_student t;--查询数据,并且给sex字段的值为别名
update dh10_student t set t.stu_sex=0 where t.stu_id=1; -- 修改
delete dh10_student t where t.stu_id = 3;--删除
·使用JDBC连接数据库:JDBC是Java连接数据库的标准,就是说要使用Java连接数据库的话,必须要使用到JDBC。
·JDBC的操作步骤:
·加载驱动程序
·连接数据库,通过Connection接口和DriverManager类完成数据库连接
·操作数据库,对于数据库的更新使用Statement或者PrepedStatement,对于查询,使用ResultSet,那么这三个都是接口。
·关闭操作,数据库的资源是非常有限的,如果操作完成之后不关闭,就可能会造成数据库服务器的宕机。
对于数据库操作,如果是更新(增删改)需要进行事务的处理。
新增操作:
package com.wanczy.oracle;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCDemo01 {
public static final String DBURL="jdbc:oracle:thin:@604-43:1521:wanczy";
public static final String ORACLEDRIVER = "oracle.jdbc.driver.OracleDriver";
public static final String DBNAME = "jjm";
public static final String PASSWORD = "jjm";
public static void main(String[] args) {//是Java运行的入口方法
Connection conn = null;
PreparedStatement pstat = null;
try {
Class.forName(ORACLEDRIVER);//加载驱动
conn = DriverManager.getConnection(DBURL, DBNAME, PASSWORD);//取得数据库连接
conn.setAutoCommit(false);//取消自动提交
String sql = "insert into dh10_student (stu_id,stu_name,stu_age,stu_sex) values (?,?,?,?)";
pstat = conn.prepareStatement(sql);//取得预处理的对象
pstat.setInt(1, 3);
pstat.setString(2, "李四");
pstat.setInt(3, 21);
pstat.setInt(4, 1);
pstat.execute();//执行
conn.commit();//如果没有异常进行提交
} catch (Exception e) {
try {
conn.rollback();//如果出现异常则回滚
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally{
try {
pstat.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
对于删除和修改,只需要修改sql和pstat的设置 的值就OK了。
对于查询需要使用ResultSet接口接收查询的结果集。
package com.wanczy.oracle;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCDemo02 {
public static final String DBURL="jdbc:oracle:thin:@604-43:1521:wanczy";
public static final String ORACLEDRIVER = "oracle.jdbc.driver.OracleDriver";
public static final String DBNAME = "mlz";
public static final String PASSWORD = "mlz";
public static void main(String[] args) {//是Java运行的入口方法
Connection conn = null;
PreparedStatement pstat = null;
ResultSet res = null;
try {
Class.forName(ORACLEDRIVER);//加载驱动
conn = DriverManager.getConnection(DBURL, DBNAME, PASSWORD);//取得数据库连接
String sql = "select t.stu_id,t.stu_name,t.stu_age ,decode(nvl(t.stu_sex,0),0,'女',1,'男') from dh10_student t";
pstat = conn.prepareStatement(sql);//取得预处理的对象
res = pstat.executeQuery();//执行查询
while(res.next()){
System.out.println("ID:" + res.getInt(1)+"\t" + "姓名:" + res.getString(2)+"\t" +"年龄:" + res.getInt(3)+"\t" +"性别:" + res.getString(4)+"\t" );
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
res.close();
pstat.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
对于JDBC的操作基本上能够了解。
对于我们昨天的WEB程序,怎么去进行数据库操作呢?
使用DAO设计模式:
DAO:数据库访问对象,Data Access Object,用对象的形式来操作数据库。之前我们第一阶段的时候使用DAO模式,但是我们使用并不全面,对于数据库访问程序来说,应该使用面向对象的特征将程序进行包装,形成一个可重用的组件。
DAO设计模式的流程:
DAO 的组成:
·POJO:每个POJO的对象就是数据库中的一笔数据(表名+POJO)
·DAO:操作的接口,每个DAO接口按照功能的需求规定了一组对数据库的操作方法。(表名+DAO),DAO中的方法命名应该按照您跟以下的命名规则:
|·更新数据库操作doXXX(),新增doIns(),doUpd(),doDel
|·查询数据库操作:findXXX,查询全部findAll(),findByUsername()根据用户名查询,findById()根据ID查询
·实现类:是完成数据库操作的一个核心类,并且不专门去管理数据库连接的取得和关闭,因为实现类完成的是和具体业务相关的操作。
·代理类:代理完成数据流连接的取得和关闭,并且调用真实主题类(实现类)。
·工厂类:有接口就必须要有工厂,进行的是解耦合的操作。
参考代码:JavaWebDemo01/
·com.wanczy.login
·jsp/login
注意:之前的javaweb的开发中,在jsp中连接了数据库,但是现在要说的一点,在以后的开发中,jsp中是绝对不允许导入sql包的。DAO完成之后,实际上就是按照一个组件方法运行。
范例:登录程序
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名" />
<EditText
android:id="@+id/username"
android:layout_width="100px"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密 码" />
<EditText
android:id="@+id/password"
android:layout_width="100px"
android:layout_height="wrap_content"
android:password="true"
/>
</LinearLayout>
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
/>
</LinearLayout>
关键就是在Activity通过Http向Web服务器发送请求。
package com.example.loginproject;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText username = null;
private EditText password = null;
private Button login = null;
private String inUsername = null;
private String inPassword = null;
private Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 1:
Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_LONG).show();//接收到子线程的消息之后进行提示
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
this.username = (EditText) super.findViewById(R.id.username);
this.password = (EditText) super.findViewById(R.id.password);
this.login = (Button) super.findViewById(R.id.login);
this.login.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// MainActivity.this.inUsername = MainActivity.this.username.getText().toString();
// MainActivity.this.inPassword = MainActivity.this.password.getText().toString();
// if(null == MainActivity.this.inUsername ||"".equals(MainActivity.this.inUsername)){
// Toast.makeText(MainActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
// return;
// }
// if(null == MainActivity.this.inPassword ||"".equals(MainActivity.this.inPassword)){
// Toast.makeText(MainActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
// return;
// }
new Thread(new Runnable(){
public void run(){
try{
URL url = new URL("http","www.wanczymis.com",80,"/jsp/BaomingJsp.jsp?stu_num=1001&stu_name=abc&stu_tel=13515967537&stu_qq=544130858&stu_dorm=501&stu_sex=1");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();//取得连接
byte b[] = new byte[1024];
int len = conn.getInputStream().read(b);//接收数据
String info = "报名失败";
if(len>0){
String s = new String(b,0,len).trim();
boolean bool = Boolean.parseBoolean(s);
if(bool){
info = "报名成功";
}
}else{
info ="连接失败";
}
Message mess = new Message();
mess.what = 1;
mess.obj = info;
MainActivity.this.myHandler.sendMessage(mess);//发送消息
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
});
}
}
以后在进行网络请求的时候必须使用子线程。
当然也需要配置权限。
<uses-permission android:name="android.permission.INTERNET"/>
以上就是使用Get进行提交,其实这种方式就是地址重写的方式,会受到地址长度的限制,所以在以后的开发中,一般使用post提交。
修改以上的程序,使用post方式进行提交。
package com.example.loginproject;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.content.Entity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText username = null;
private EditText password = null;
private Button login = null;
private String inUsername = null;
private String inPassword = null;
private Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 1:
Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_LONG).show();//接收到子线程的消息之后进行提示
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
this.username = (EditText) super.findViewById(R.id.username);
this.password = (EditText) super.findViewById(R.id.password);
this.login = (Button) super.findViewById(R.id.login);
this.login.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MainActivity.this.inUsername = MainActivity.this.username.getText().toString().trim();
MainActivity.this.inPassword = MainActivity.this.password.getText().toString().trim();
if(null == MainActivity.this.inUsername ||"".equals(MainActivity.this.inUsername)){
Toast.makeText(MainActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
return;
}
if(null == MainActivity.this.inPassword ||"".equals(MainActivity.this.inPassword)){
Toast.makeText(MainActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
return;
}
new Thread(new Runnable(){
public void run(){
try{
String url = "http://172.26.64.60:8080/AndroidTestWeb/LoginServlet";
HttpPost request = new HttpPost(url);
List<NameValuePair> params = new ArrayList<NameValuePair>();//用来保存参数
params.add(new BasicNameValuePair("username", MainActivity.this.inUsername));
params.add(new BasicNameValuePair("password", MainActivity.this.inPassword));
request.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));//设置编码
HttpResponse response = new DefaultHttpClient().execute(request);//接收回应
boolean bool = false;
String info = "登录失败";
if(response.getStatusLine().getStatusCode()!=404 && response.getStatusLine().getStatusCode()!=500){
String s = EntityUtils.toString(response.getEntity()).trim();
bool = Boolean.parseBoolean(s);
if(bool){
info = "登录成功";
}
}else{
info ="连接失败";
}
Message mess = new Message();
mess.what = 1;
mess.obj = info;
MainActivity.this.myHandler.sendMessage(mess);//发送消息
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
});
}
}
范例:获取网络上图片。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Activity程序。
package com.example.getimageproject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView img = null;
public static final String PATH = "http://www.wanczy.com/upload_images/20131101152009_912.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
this.img = (ImageView) super.findViewById(R.id.img);
byte b[] = new byte[1024];
try {
b = this.getURLData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeByteArray(b, 0, b.length);
this.img.setImageBitmap(bm);
}
public byte[] getURLData() throws Exception{
ByteArrayOutputStream bos = null;//内存输出流
try{
URL url = new URL(PATH);
bos = new ByteArrayOutputStream();
byte b[] = new byte[1024];
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
InputStream in = conn.getInputStream();//取得网络上字节输入流
int temp = 0;//这个是一个过渡的变量,将字节输入流一个一个读取,赋值为temp,然后写入到内存输出刘中
while((temp = in.read(b))!= -1){//将内容读取到字节数组中并且赋值给temp,且如果读取内容不为-1的话表示还可以继续往下读
bos.write(b,0,temp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return bos.toByteArray();
}
}
如果使用子线程怎么完成?
package com.example.getimageproject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView img = null;
public static final String PATH = "http://www.wanczy.com/upload_images/20131101152009_912.jpg";
ByteArrayOutputStream bos = null;// 内存输出流
private Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
byte b[] = new byte[1024];
b = (byte[]) msg.obj;
Bitmap bm = BitmapFactory.decodeByteArray(b, 0, b.length);
MainActivity.this.img.setImageBitmap(bm);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
this.img = (ImageView) super.findViewById(R.id.img);
MainActivity.this.bos = new ByteArrayOutputStream();
new Thread(new Runnable(){
public void run(){
try{
byte b[] = new byte[1024];
URL url = new URL(PATH);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream in = conn.getInputStream();// 取得网络上字节输入流
int temp = 0;// 这个是一个过渡的变量,将字节输入流一个一个读取,赋值为temp,然后写入到内存输出刘中
while ((temp = in.read(b)) != -1) {// 将内容读取到字节数组中并且赋值给temp,且如果读取内容不为-1的话表示还可以继续往下读
MainActivity.this.bos.write(b, 0, temp);
}
Message msg = new Message();
msg.what =1;
msg.obj = MainActivity.this.bos.toByteArray();
MainActivity.this.myHandler.sendMessage(msg);
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}
对于以后开发网络请求,都需要使用到子线程进行提交请求。
1.3 小结
(1)如果需要网络则必须具有网络访问的权限;
(2)连接WEB Server的时候可以使用地址重写的方式,也可以使用POST提交的方式;
(3)使用Bitmap可以将读取下来的图片数据设置到ImageView中进行显示。
(4)对于以后网络请求开发,必须要使用到子线程进行。