美文网首页
JavaWeb之Servlet&网络访问服务器编程

JavaWeb之Servlet&网络访问服务器编程

作者: 征程_Journey | 来源:发表于2017-05-21 11:31 被阅读0次

1      Servlet&网络访问

1.1    网路基础

B/S的S  Server http网络应用服务端软件

http Hyper Text Transmission Protocol 超文本传输协议,处于四层架构中的应用层,是建立TCP的基础上

网络应用服务端软件可以看成一个容器,我们将网络应用部署到其中并启动,这个容器就可以按照我们的意愿去工作,处理客户端的请求并响应

常用网络应用服务端软件:Tomcat、JBoss、Websphere、WebLogic

如何写Web项目:

1、HttpServlet 小的服务端组件 定义一个类继承它

2、重写其中的doGet、doPost方法,在这两个方法里写上如何处理客户端的请求,这两个方法是回调方法,doGet处理Get请求、doPost处理Post请求

3、在web.xml中注册这个类,告诉容器在处理某一类型请求的时候,使用这个类中的逻辑

可以使用HttpServletRequest的getParameter方法获取请求中某参数的值

可以使用HttpServletResponse的getOutputStream方法获取响应的输出流,给客户端写信息

C/S 中的 C

URL类  Uniform Resource Locator统一资源定位器

构造方法:URL(String url)把一个字符串形式的url构建出一个URL对象

openConnection() 获取网络连接URLConnection对象,一般会将其强转为HttpURLConnection类型,并作相应操作。(调用这个方法时这个连接并没有真正产生)

HttpURLConnection 类

主要方法:

connect() 产生真正的连接

getInputStream() 获取响应体输入流,可以用来接收服务端响应

getResponseCode()获取响应状态码,200为正常,这个方法必须在连接之后以及请求发出去之后才调用,否则它会隐式调用connect()方法,出现一些奇怪的状况

getOutputStream()获取请求体的输出流,可以往请求体中写

setRequestMethod()设置请求方式,默认为GET,如果是POST方式就一定要使用这个方法

setDoOutput() 设置是否可以往连接中输出,默认是false,如果是POST方式,一定要设为true

setDoInput() 设置是否可从连接中读出,默认为true,所以这个方法不需要使用

GET请求:

把参数放在url里面,和服务端连接,读取服务端响应

1、创建URL(后面跟着参数 )

2、获取连接

3、产生连接

4、判断状态码,是200就读取响应内容

POST请求:

1、创建URL(后面没参数)

2、获取连接

3、设置请求方法setRequestMethod("POST")

设置允许输出setDoOutput(true),允许往请求(体)里写

4、产生连接

5、获取连接的输出流,往请求(体)中写参数

6、读取响应内容

1.2    Web概述

1.2.1  网络架构:C/S 与 B/S之争

C/S:Client/Server:《优点:客户端可以任意设计,可以展示绚丽的效果和特殊功能;对于网速的依赖没有B/S那么强

缺点:使用时需要下载客户端并安装,所有客户端都需要联网更新》

B/S:Browser/Server:《优点:不需要下载任何客户端,只要有浏览器就可以使用,当程序需要更新时,只需要在服务端进行更新即可

缺点:所有的运算都要在服务端完成,服务器压力和大,并且浏览器暂时不具备展示十分绚丽的效果的能力;十分依赖网络(网速)》

Http协议:《Hypertext Transfer Protocol:超文本传输协议,它是以TCP/IP为基础的高层协议

定义浏览器和web服务器之间交换数据的过程以及数据格式

定义Web浏览器和web服务器之间通讯的协议

现在广泛使用的版本是Http/1.1。相对于Http/1.0来说,最大的特点就是支持持续连接(即一次TCP连接上可以包含多次请求和响应)

常见状态码:《消息(1字头):100     成功(2字头):200   重定向(3字头)

请求错误(4字头):404    服务器错误(5、6字头):500》

1.3    Servlet的基本概念

Servlet是SUN公司提供的一种用于开发动态web资源的技术

Sun公司在其API中提供了一个Servlet接口,根据该接口编写的程序没有main方法。它们受控于另一个Java应用,这个Java应用称为Servlet容器,Tomcat就是这样一个容器

1.3.1  Servlet的登陆示例

Inserttitle here

-->

action:服务器的地址

method:数据的提交方式,常用的有两种:get、post

-->

用户名:

密码:

publicclass MyServlet extends HttpServlet {

// 序列值

private static final longserialVersionUID = 1L;

/**

* @see HttpServlet#HttpServlet()

*/

public MyServlet() {

super();

// TODO Auto-generated constructor stub

}

/**

*

* 用于处理来自客户端的网络请求(get方式)

* 参数1:request,来自客户端的请求对象,封装了客户端向服务端发送的请求数据

* 参数2:response,通过该对象可以向客户端做出响应

*/

protected void doGet(HttpServletRequestrequest, HttpServletResponse response) throws ServletException, IOException {

// 获取账号、密码

response.setCharacterEncoding("GBK");

String name= request.getParameter("username");

String pwd= request.getParameter("pwd");

System.out.println(name+ "..." + pwd);

if("admin".equals(name)&& "123".equals(pwd)) {

//登陆成功

response.getWriter().print("loginsuccess...(登陆成功)");

} else {

//登陆失败

response.getWriter().print("loginfailed...(登陆失败)");

}

}

/**

* 用于处理来自客户端的网络请求(post方式)

*/

protected voiddoPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

// TODO Auto-generated methodstub

this.doGet(request,response);

}

}

基于JSP的实现形式:

<%@page language="java" import="java.util.*"pageEncoding="utf-8"%>

<%

Stringpath = request.getContextPath();

%>

测试HTTP协议体的内容

-->

-->

/servlet/LoginAction">

用户名:


密  码:


publicclass LoginAction extends HttpServlet {

/**

* Constructor of the object.

*/

public LoginAction() {

super();

}

/**

* Destruction of the servlet.

*/

public void destroy() {

super.destroy(); // Just puts"destroy" string in log

// Put your code here

}

public void doGet(HttpServletRequestrequest, HttpServletResponse response)

throwsServletException, IOException {

this.doPost(request,response);

}

public void doPost(HttpServletRequestrequest, HttpServletResponse response)

throwsServletException, IOException {

response.setContentType("text/html;charset=utf-8");

request.setCharacterEncoding("utf-8");

response.setCharacterEncoding("utf-8");

PrintWriter out =response.getWriter();

String username =request.getParameter("username");

System.out.println("-username->>"+username);

String pswd =request.getParameter("password");

System.out.println("-password->>"+pswd);

if(username.equals("admin")&&pswd.equals("123")){

//表示服务器端返回的结果

out.print("loginis success!!!!");

}else{

out.print("loginis fail!!!");

}

out.flush();

out.close();

}

public void init() throwsServletException {

// Put your code here

}

}

1.4    网络访问

1.4.1  URL

什么是URL?:《URL(UniformResource Locator)是统一资源定位符的简称

表示Intent上某一资源的地址

通过URL可以访问Intenet上的各种网络资源,比如常见的www、FTP站点》

URL的基本结构由5部分组成:《<传输协议>://<主机名>:<端口号>/<文件名>#<引用>

http://www.tomcat.com:80/Gamelan/network.html#BOTTOM》

1.4.2  获取网络数据

方式一:HttpUrlConnection类:《1、获取网络连接对象

1、 设置网络数据请求的方式(默认GET)

2、 设置连接超时的时间,如果超时,说明没有连接成功,就会抛出异常

3、 设置接收数据超时的时间,如果超时,就会排除异常

4、 验证服务器的返回码

5、 通过IO流传输数据

6、 解析数据

PS:POST请求需要另外设置请求参数

Content-Type:application/x-www-form-urlencoded

Content-Length: 数据的大小

方式二:ApacheHttpClient框架:【

《HttpClient是由Apache开源组织提供的一个开源项目,它是一个简单的Http客户端(并不是浏览器),可以用于发送Http请求,接收Http响应》

《简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做。HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理Http的连接》

Android已经成功集成了HttpClient:Android6.0开始,已经将HttClient框架从AndroidSDK中移除》

1.4.3  Apache HttpClient框架

《注意:需要加入外部的Java包。

publicclass Demo {

public static void main(String[] args){

// TODO Auto-generated methodstub

//               doGetByHttpClient();

doPostByHttpClient();

}

private static voiddoPostByHttpClient() {

// TODO Auto-generated methodstub

HttpClient client = null;

try {

client = newDefaultHttpClient();

HttpPost post = newHttpPost("http://api.k780.com:88/");

//保存请求参数的集合对象

Listlist = new ArrayList<>();

//将请求参数封装成对象存入集合中,每一个NameValuePair对象封装了一组键值对

list.add(newBasicNameValuePair("app", "weather.today"));

list.add(new BasicNameValuePair("weaid","1"));

list.add(newBasicNameValuePair("appkey", "15250"));

list.add(newBasicNameValuePair("sign","f88a5cecc3cbd37129bc090c0ae29943"));

list.add(newBasicNameValuePair("format", "json"));

HttpEntity httpEntity = newUrlEncodedFormEntity(list);

post.setEntity(httpEntity);

HttpResponse response =client.execute(post);

int code =response.getStatusLine().getStatusCode();

if(code == 200){

InputStream is =response.getEntity().getContent();

String result =readStream(is);

System.out.println(result);

}

} catch(UnsupportedEncodingException e) {

// TODOAuto-generated catch block

e.printStackTrace();

} catch(IllegalStateException e) {

// TODOAuto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODOAuto-generated catch block

e.printStackTrace();

}finally{

if(client != null){

client.getConnectionManager().shutdown();

client =null;

}

}

}

private static void doGetByHttpClient(){

// TODO Auto-generated methodstub

HttpClient client = null;

try {

client  = new DefaultHttpClient();

HttpGet get = newHttpGet("http://api.k780.com:88/?app=weather.today&weaid=1&&appkey=15250&sign=f88a5cecc3cbd37129bc090c0ae29943&format=json");

//访问网络资源

HttpResponseresponse = client.execute(get);

//获取状态码

int code=response.getStatusLine().getStatusCode();

if(code == 200){

InputStreamis = response.getEntity().getContent();

Stringresult = readStream(is);

System.out.println(result);

}else{

throw newRuntimeException("网络访问失败:"+code);

}

} catch(ClientProtocolException e) {

// TODOAuto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODOAuto-generated catch block

e.printStackTrace();

}finally{

if(client !=null){

client.getConnectionManager().shutdown();

client =null;

}

}

}

public static StringreadStream(InputStream is) throws IOException{

ByteArrayOutputStream baos =new ByteArrayOutputStream();

byte[] buf = new byte[1024];

int len = 0;

while((len=is.read(buf))!=-1){

baos.write(buf, 0,len);

}

return newString(baos.toByteArray(), "utf-8");

}

}

1.5    K780数据网

K780数据网,测试账号

《Appkey:15250     Secret:2bbebb3e480a850df6daca0c04a954e1

Sign:f88a5cecc3cbd37129bc090c0ae29943》

1.6    示例使用Post和Get请求网络数据

publicclass NetPostGet {

/**

* @param args

*/

public static void main(String[] args){

// TODO Auto-generated methodstub

// doGet();

doPost();

}

// 使用post方式请求网络数据

private static void doPost() {

HttpURLConnection conn =null;

try {

URL url = newURL("http://api.k780.com:88/");

conn =(HttpURLConnection) url.openConnection();

String data ="app=weather.today&weaid=1&&appkey=15250&sign=f88a5cecc3cbd37129bc090c0ae29943&format=json";

conn.setRequestMethod("POST");

conn.setReadTimeout(5000);

conn.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded");

conn.setRequestProperty("Content-Length",data.length() + "");

// post网络访问必须实现

conn.setDoInput(true);

conn.setDoOutput(true);

// 注意要将请求的内容写到请求体中去

conn.getOutputStream().write(data.getBytes());

conn.connect();

int code =conn.getResponseCode();

if (code == 200) {//表示访问成功

InputStreamis = conn.getInputStream();

System.out.println(readStream(is));

} else {

System.out.println("网络数据访问失败:" + code);

}

} catch(MalformedURLException e) {

// TODOAuto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODOAuto-generated catch block

e.printStackTrace();

} finally {

if (conn != null) {

conn.disconnect();

conn =null;

}

}

}

// 使用get方式请求网络数据

private static void doGet() {

HttpURLConnection conn =null;

try {

URL url = new URL(

"http://api.k780.com:88/?app=weather.today&weaid=1&&appkey=15250&sign=f88a5cecc3cbd37129bc090c0ae29943&format=json");

conn =(HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

conn.setReadTimeout(5000);

conn.setReadTimeout(5000);

conn.connect();

int code =conn.getResponseCode();

if (code == 200) {

InputStreamis = conn.getInputStream();

System.out.println(readStream(is));

} else {

System.out.println("获取数据失败:" + code);

}

} catch(MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (conn != null) {

conn.disconnect();

conn =null;

}

}

}

public static StringreadStream(InputStream is) throws IOException {

ByteArrayOutputStream baos =new ByteArrayOutputStream();

int len = 0;

byte[] buf = new byte[1024];

while ((len = is.read(buf))!= -1) {

baos.write(buf, 0,len);

}

return newString(baos.toByteArray(), "utf-8");

}

}

1.7    网络访问工具类封装

publicclass HttpUtils {

private static final int TIMEOUT =10000;

//返回一个字节数组

public static byte[] doGet(Stringpath){

try {

URL mUrl = newURL(path);

HttpURLConnectionconn = (HttpURLConnection)mUrl.openConnection();

conn.setRequestMethod("GET");

conn.setReadTimeout(TIMEOUT);

conn.setReadTimeout(TIMEOUT);

conn.connect();

int code =conn.getResponseCode();

if(code == 200){

return readStream(conn.getInputStream());

}else{

throw newRuntimeException("网络访问失败:"+code);

}

} catch(MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

public static byte[] doPost(String url,String params) {

HttpURLConnection conn =null;

try {

URL mUrl = newURL(url);

conn =(HttpURLConnection) mUrl.openConnection();

conn.setRequestMethod("POST");

conn.setConnectTimeout(TIMEOUT);

conn.setReadTimeout(TIMEOUT);

// 设置请求属性

conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

conn.setRequestProperty("Content-Length",params.length()+"");

// Post请求必须要写以下两行代码

conn.setDoInput(true);

conn.setDoOutput(true);

// 将请求参数写到请求体中

conn.getOutputStream().write(params.getBytes());;

conn.connect();

int code =conn.getResponseCode();

if(code == 200) {

returnreadStream(conn.getInputStream());

} else {

throw newRuntimeException("网络访问失败:"+ code);

}

} catch (Exception e) {

e.printStackTrace();

return null;

} finally {

if(conn != null) {

conn.disconnect();

conn =null;

}

}

}

//返回一个字符串

public static String doGetStr(Stringpath) throws IOException{

byte[] data = doGet(path);

return new String(data, "utf-8");

}

private static byte[]readStream(InputStream is) throws IOException{

ByteArrayOutputStream baos =new ByteArrayOutputStream();

byte[] buf = new byte[1024];

int len =0;

while((len =is.read(buf))!=-1){

baos.write(buf, 0,len);

}

return baos.toByteArray();

}

}

1.8    总结

在Android中对网络请求最基本的实现有两种

1、  HttpURLConnection

是JDK自带的实现方式,实现方式相对比较繁琐,也比较灵活

2、  HttpClient框架

底层代码还是基于HttpURLConnection,只是对HttpURLConnection进行了更深层次的封装

是apache开源组织开发的开源框架,实现方式相对简单一些,相对HttpURLConnection来说,没有那么灵活

Android在SDK(SoftwareDevelopment Kit)中已经集成了HttpClient框架

不过,Android在6.0开始,就已经将HttpClient框架从SDK中移除了

相关文章

网友评论

      本文标题: JavaWeb之Servlet&网络访问服务器编程

      本文链接:https://www.haomeiwen.com/subject/ijbmxxtx.html