美文网首页
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