网络编程
- 向服务端发送网络请求,接收服务端返回的内容
查询手机号的归属地和运营商
public static void main(String[] args) {
// 查询接口地址链接
String httpUrl = "http://apis.baidu.com/apistore/mobilenumber/mobilenumber";
// 查询参数
String httpArg = "phone=18381312219";
// 发送请求,查询数据
String jsonResult = request(httpUrl, httpArg);
// 用第三方jar包解析服务器返回的json数据
ObjectMapper mapper = new ObjectMapper();
try {
Information i = mapper.readValue(jsonResult, Information.class);
System.out.println("运营商:"+i.getRetData().getSupplier() + "\n省份:"+i.getRetData().getProvince() + "\n城市:"+i.getRetData().getCity());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 向服务端发起请求,接收服务端返回的内容
*
* GET请求:参数拼接在接口地址的后面,多个参数使用&符号拼接
*/
public static String request(String httpUrl, String httpArg) {
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?" + httpArg;
try {
// URL代表一个统一资源定位符,它是指向互联网“资源”的指针。就是一个资源的地址
URL url = new URL(httpUrl);
// 表示到 URL 所引用的远程对象的连接。
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// GET POST PUT HEAD DELETE...Http协议的请求方式
connection.setRequestMethod("GET");
// 填入apikey到HTTP header
connection.setRequestProperty("apikey", "f6be49bd291a1467f641d55041e33c26");
// 建立程序和远程资源的连接
connection.connect();
// 获取输入流:一端我们的程序,另一端远程资源
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);// 读取返回的数据
sbf.append("\r\n");
}
reader.close();
result = sbf.toString();// 存放返回的所有数据
} catch (Exception e) {
e.printStackTrace();
}
return result;// 返回读取到的数据
}
Http协议
请求部分:
- 1、请求行(request line)
- 2、request header:请求头,都是键值对的形式存在
- User-Agent:当前使用的浏览器
- 3、空行
- 4、request body:请求内容:get请求的请求内容是拼接url之后的,在request body中是没有的
响应部分:
- 1、响应行、状态行(status line)
- 2、response header:响应头
- 3、空行
- 4、response body:响应的内容,显示在浏览器上
线程
开启一个线程的用途就是让程序同时进行两个事件。如我们要下载两张图片,第一张图片大小为1G,第二张为1M,开启线程就可以点击按钮第一张图片开始下载,这时候直接再点击第二张图片开始下载第二张图片。
线程:就是程序中的一个运行路径 虚拟机调用main方法,已经开启了一个线程,称为主线程或main线程
进程:一个运行中的程序,一个进程可能会包含多个线程。
- 如何写一个线程?
- 1、继承Thread类
- 重写其run方法
- 开启线程:使用Thread类的start方法,通知虚拟机,完成新线程的开启。
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();// 开启新线程,线程开启之后会执行run方法里的内容
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我打boss");
}
}
// 继承Thread类
private static class MyThread extends Thread {
@Override
public void run() {// 重写run方法
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Boss打我");
}
}
}
- 2、实现Runnable接口,
- 重写其run方法
- 使用Thread类的start方法
public static void main(String[] args) {// 主线程
MyThread mt = new MyThread();
Thread th = new Thread(mt);
th.start();// 开启线程
}
// 实现Runnable接口
private static class MyThread implements Runnable {
@Override
public void run() {// 重写run方法
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Boss打我");
}
}
}
线程的用处:
- 1、可以充分利用cpu资源,加快程序运行速度。
2、在Android中,开启新线程去做一些耗时的工作。
timer类(定时器)的使用
public static void main(String[] args) {
Timer timer = new Timer();
// 1、表示需要执行的任务 2、表示延迟时间 3、执行频率(每隔多少秒执行)
timer.schedule(new TimerTask(){
@Override
public void run() {
System.out.println("小怪发射了一颗子弹");
}
},1000, 2000);
}
- 牛刀小试
下载一个图片网站上10页的图片。每页有50张图片。开启10个线程下载
Tomcat的使用
先将Tomcat和Eclipse关联,方法不会可以百度。Eclipse内创建Dynamic Web Project工程。运用服务器编程。
相当于我们是服务器,别人来访问我们,我们将访问的客户端请求接受并进行相应的处理,然后返回给用户一个结果。
实现服务端注册功能,用户输入用户名、密码,我们服务端将用户的用户名、密码存储在本地对应文件中。
@WebServlet("/register")// 必须写,这是域名的配置
public class RegisterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public RegisterServlet() {
super();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取用户传入的参数信息
String username = req.getParameter("username");
String password = req.getParameter("password");
// 开启本地文件的写入流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File("F:/abc/a.txt"))));
// 将用户信息写入本地文件中
pw.println(username);
pw.println(password);
pw.close();
}
}
// 用户访问的地址链接:HelloWeb是我们的工程名
//localhost:8080/HelloWeb/register?username=xiaobai&password=123456
手机号码查询系统
@WebServlet("/phone")
public class PhoneServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public PhoneServlet(){
super();
}
@Override
// req关于获取用户输入的对象,resp关于将本地数据返回给客户端的对象
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、处理乱码问题
resp.setContentType("text/html;charset=utf-8");
// 2、获取用户请求
String phone = req.getParameter("phone");
// 3、模拟判断程序
RetData retData = new RetData("移动","四川","自贡",phone);
// 4、将对象转为json数据
Gson gson = new Gson();
String json = gson.toJson(retData);
// 5、将json数据写到客户端,
PrintWriter pw = resp.getWriter();
pw.println(json);
pw.close();
}
}