介绍
随着PC机的诞生与应用,计算模式从集中式(数据和应用程序在一台主机上)转向了分布式(数据和应用程序跨越多个节点机),尤为典型的是C/S结构(Client/Server的简称,客户机/服务器模式)。两层结构C/S模式,在上个世纪八十年代及九十年代初得到了大量应用,最直接的原因是可视化开发工具的推广。之后,它开始向三层结构发展。近来,随着网络技术不断发展,尤其是基于Web的信息发布和检索技术、Java计算技术以及网络分布式对象技术的飞速发展,导致了很多应用系统的体系结构从C/S结构向更加灵活的多级分 布结构演变,使得软件系统的网络体系结构跨入一个新阶段,即B/S体系结构(Browser/Server的简称,浏览器/服务器模式)。基于Web的B/S方式其实也是一种客户机/服务器方式,只不过它的客户端是浏览器。为了区别于传统的C/S模式,才特意将其称为B/S(浏览器/服务器)模式。
结合今天知识点
Client
以下几个方法,相当于客户端,在做界面时用到了类 JFrame了解请点击!
界面的文本输入,按钮等都可以在这里面实现。
1、doGet
直接连接在url后面是显示的
GET 调用用于获取服务器信息,并将其做为响应返回给客户端。当经由Web浏览器或通过HTML、JSP直接访问Servlet的URL时,一般用GET调用。 GET调用在URL里显示正传送给SERVLET的数据,这在系统的安全方面可能带来一些问题,比如用户登录,表单里的用户名和密码需要发送到服务器端, 若使用Get调用,就会在浏览器的URL中显示用户名和密码。
测试方法代码:
public class DoGet extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DoGet frame = new DoGet();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public DoGet() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 320);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JButton btnDoget = new JButton("doGet方法测试");
btnDoget.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String urlString = "http://localhost:8080/MyServiceTest/MyTest?username=李三&password=11114";
//直接跟在url后是doGet方法
try {
URL url = new URL(urlString);//生成URL
URLConnection connect = url.openConnection();//打开url连接
HttpURLConnection httpConnection = (HttpURLConnection) connect;//HttpUrlConnection 是sun封装成的网络连接
httpConnection.setRequestMethod("GET");//设置请求方法
httpConnection.setConnectTimeout(3000);//设置连接超时的时间
httpConnection.setReadTimeout(3000);//读取时间超时
// 设置编码方式,接受的数据类型
httpConnection.setRequestProperty("Accept-Charset", "utf-8");//使用utf-8编码格式将字节数组转化成字符串
// 设置可以接受序列化的java对象
httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
int code = httpConnection.getResponseCode();//得到状态码
System.out.println(code);
if(code==HttpURLConnection.HTTP_OK){//网络连接状态成功,那么下面读数据
InputStream is = httpConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = br.readLine();
while(line!=null){
System.out.println(line);
line = br.readLine();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SocketTimeoutException e) {
System.out.println("连接超时");
// TODO: handle exception
}
catch (ConnectException e) {
System.out.println("连接失败");
// TODO: handle exception
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
btnDoget.setBounds(101, 86, 135, 98);
contentPane.add(btnDoget);
}
}
2.HttpClientDoGet
HttpClient 是apache使用httpUrlConnection封装的类
方法的测试
代码如下:
public class HttpClinetdoGet extends JFrame {
private JPanel contentPane;
private JTextField textFieldUsername;
private JTextField textFieldPassword;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
HttpClinetdoGet frame = new HttpClinetdoGet();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public HttpClinetdoGet() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 310, 301);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
JButton btnNewButton = new JButton("New button");//按钮
btnNewButton.setBounds(95, 150, 93, 76);
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String username = textFieldUsername.getText();//输入界面输入用户名和密码
String password = textFieldPassword.getText();
String urlString = "http://localhost:8080/MyServiceTest/MyTest?username="+username+"&password="+password+"";
HttpClientBuilder builder = HttpClientBuilder.create(); // 生成client的builder
builder.setConnectionTimeToLive(3000, TimeUnit.MILLISECONDS);
HttpClient client = builder.build();//生成client
HttpGet get = new HttpGet(urlString);//设置为get方法
//设置服务器接收后数据的读取方式为utf-8
get.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
try {
HttpResponse response = client.execute(get);//执行get方法得到服务器的返回的所有数据都在response中
StatusLine statusLine = response.getStatusLine();//httpClient访问服务器返回的表头,包含http状态码
int code = statusLine.getStatusCode();//得到状态码
if (code == HttpURLConnection.HTTP_OK) {
HttpEntity entity = response.getEntity();//得到数据的实体
InputStream is = entity.getContent();//得到输入流
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = br.readLine();
while (line != null) {
System.out.println(line);
line = br.readLine();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
contentPane.setLayout(null);
contentPane.add(btnNewButton);
textFieldUsername = new JTextField();
textFieldUsername.setBounds(107, 40, 66, 21);
contentPane.add(textFieldUsername);
textFieldUsername.setColumns(10);
textFieldPassword = new JTextField();
textFieldPassword.setBounds(107, 104, 66, 21);
contentPane.add(textFieldPassword);
textFieldPassword.setColumns(10);
}
}
3、DoPost
它用于客户端把数据传送到服务器端,也会有副作用。但好处是可以隐藏传送给服务器的任何数据。Post适合发送大量的数据。
主要Java代码如下:
JButton btnPost = new JButton("Post方法测试");
btnPost.setBounds(84, 140, 152, 90);
btnPost.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String urlString = "http://localhost:8080/MyServiceTest/MyTest";
//直接跟在url后是doGet方法
try {
URL url = new URL(urlString);//生成URL
URLConnection connect = url.openConnection();//打开url连接
HttpURLConnection httpConnection = (HttpURLConnection) connect;
httpConnection.setRequestMethod("POST");//设置请求方法
httpConnection.setConnectTimeout(30000);//设置连接超时的时间
httpConnection.setReadTimeout(30000);//读取时间超时
// 设置编码方式,接受的数据类型
httpConnection.setRequestProperty("Accept-Charset", "UTF-8");
// 设置可以接受序列化的java对象
httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConnection.setDoInput(true);//设置可以读取服务器返回的内容,默认是true
httpConnection.setDoOutput(true);//设置客户端可以给服务器提交数据,默认是false。post方法必须设置为true
httpConnection.setUseCaches(false);//post方法不允许使用缓存
String username = textFieldUsername.getText();
String password = textFieldPassowrd.getText();
String params = "username="+username+"&password="+password;
//String params = "username=lisi&password=1234";
httpConnection.getOutputStream().write(params.getBytes());
int code = httpConnection.getResponseCode();
System.out.println(code);
if(code==HttpURLConnection.HTTP_OK){
InputStream is = httpConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = br.readLine();
while(line!=null){
System.out.println(line);
line = br.readLine();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SocketTimeoutException e) {
System.out.println("连接超时");
// TODO: handle exception
}
catch (ConnectException e) {
System.out.println("连接失败");
// TODO: handle exception
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
contentPane.setLayout(null);
contentPane.add(btnPost);
4、HttpClientDoPost
主要Java代码如下
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
/* (non-Javadoc)
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent e) {
String url = "http://localhost:8080/MyServiceTest/MyTest";
HttpClientBuilder builder = HttpClientBuilder.create(); // 生成client的builder
builder.setConnectionTimeToLive(3000, TimeUnit.MILLISECONDS);
HttpClient client = builder.build();//生成client
HttpPost post = new HttpPost(url);
NameValuePair pair1 = new BasicNameValuePair("username", "小孩");
NameValuePair pair2 = new BasicNameValuePair("password", "123456");
ArrayList<NameValuePair> params = new ArrayList<>();
params.add(pair1);
params.add(pair2);
try {
post.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
post.setHeader("Content", "application/x-www-form-urlencoded;charser=UTF-8");
HttpResponse response = client.execute(post);
int code = response.getStatusLine().getStatusCode();
if(code==200){
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = br.readLine();
if(line!=null){
System.out.println(line);
line = br.readLine();
}
}
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
btnNewButton.setBounds(114, 145, 93, 55);
contentPane.add(btnNewButton);
Servlet
1、首先要有SQLManager类,与数据库建立连接
public class SQLManager {
private Statement statement;
private Connection con;
public Connection getCon() {
return con;
}
public void setCon(Connection con) {
this.con = con;
}
public Statement getStatement() {
return statement;
}
public void setStatement(Statement statement) {
this.statement = statement;
}
private static SQLManager manager;
public static synchronized SQLManager newInstance() {
if (manager == null) {
manager = new SQLManager();
}
return manager;
}
private SQLManager() {
// 导入数据库jar的驱动
String driver = "com.mysql.jdbc.Driver";
// URL指向要访问的数据库名
String url = "jdbc:mysql://localhost:3306/clazz";
// mysql配置时的用户名
String user = "root";
// Java连接mysql配置时的密码
String password = "123456";
try {
Class.forName(driver);// 加载驱动
con = DriverManager.getConnection(url, user, password);// 与数据库建立连接
// 数据库操作类
statement = con.createStatement();
System.out.println("执行完成");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2、为了防止出现乱码,建立一个转码类
public class Encoding {//这个类是用来转码,就不会出现乱码了
public static String doEncoding(String string){
try {
byte[] array = string.getBytes("ISO-8859-1");//接口
string = new String(array,"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return string;
}
}
3、Servlet类
/**
* Servlet implementation class MyTest
*/
@WebServlet("/MyTest")
public class MyTest extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MyTest() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
String username = request.getParameter("username");
String password = request.getParameter("password");
username = Encoding.doEncoding(username);//转码
String s = "用户名:" + username + " 密码:" + password;
System.out.println(s);
Connection con = SQLManager.newInstance().getCon();
try {
if (!con.isClosed()) {
PreparedStatement state = con.prepareStatement("select * from user where user_name=? and password=?");
state.setString(1, username);
state.setString(2, password);
ResultSet set = state.executeQuery();
set.last();
int num = set.getRow();
System.out.println("查询结果:" + num);
if(num==1){
System.out.println("登陆成功");
}else{
System.out.println("用户名或密码错误");
}
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// try {
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.getWriter().append(s);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}

本文介绍了计算机从集中式到分布式计算模式的转变,重点关注C/S和B/S架构。C/S模式在早期广泛使用,随着Web技术的发展,B/S模式成为主流。文中讲解了B/S模式中客户端的角色,以及GET和POST两种HTTP方法在客户端与服务器交互中的应用,并提供了相关代码示例。
1153

被折叠的 条评论
为什么被折叠?



