1该项目主要实现Android客户端以get的方式或者post的方式向java web服务器提交参数

Android客户端通过get方式或者post方式将参数提交给后台服务器,后台服务器对收到的参数进行规制校验之后,一般把数据都存储在数据库中。

现在 准备向服务器提交下面的两个参数:

1、  key videoTitle :value

2、  key videoTimeLength:value

准备将视频的名称和时间长度提交到后台服务器

java web后台的框架如上图所示

1 客户端向服务器提交参数,就会存在中文乱码的问题

向前面23 、24、55视频中讲解的中的服务器向客户端返回字符串、返回xml数据、返回json数据,客户端的编码方式都必须和服务器jsp页面中的编码方式一样,否则客户端显示的时候客户端会出现乱码

同理:客户端向服务器提交参数的时候,服务器的获得的字符串的编码方式必须和客户端的编码方式一样,否则服务器获得参数就会存在乱码问题。

客户端向服务器提交中文参数:解决乱码问题可以有下面的方式进行解决:

1、客户端指定上传参数的编码方式:

可以使用URLEncoder类指定客户端的编码方式

2、服务器按照客户端指定的编码方式编码

这里需要注意的是tomacat服务器运行默认采用iso—99859编解码。例如:客户端采用了utf-8编解码,在网络中传输的是utf-8解码的二进制数据,到了java web后台,如果不指定对应编码方式,tomacat中的servlet

会按照将字节流数据按照iso—99859编码成字符串,本来应该按照utf-8编码的,却按照iso—99859编码,这样就会引起中文乱码。

服务器这里的处理乱码的方式有下面的两种方式:

(1)服务器将获得字符串按照iso—99859解码获得网络中传输的字节流数据,然后将字节流数据按照正确的utf-8格式编码

Byte[] bytes =Title.getbytes(“iso8859-1”)就是获得原始的网络中传输的字节流

然后new String(bytes,”utf-8”)然后将字节流按照正确的方式编码就可以了

上面这种方式对post提交和get提交都有效。对应post提交还可以使用

request.setCharacterEncoding("utf-8");这种方式只能post的提交方式有效,对get的方式无效

如果工程项目中存在很多servlet,每一个servlet都这样处理,工作量会很多,为了减少工作量可以使用java web中的Filter进行处理中文的乱码问题

建立一个filter该filter对所有的request的url路径都进行过滤处理/*表示所有的请求路径

Myelipse如何创建Filter

右键,New->other->显示全部(记得勾选下边的show all wizards),就再到查找中输入filter就找到啦.

1 、该过滤类继承Filter

1、 该类的URL设置为/*

我们来看下EncodingFilter

package com.videos.utils;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest; /**
* Servlet Filter implementation class EncodingFilter
*/
@WebFilter("/*")
public class EncodingFilter implements Filter { /**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//浏览器传递过来的request进行封装,封装之后的请求对象是MyRequestWapper,该对象对
//getParameter 进行了正确的封装,ShowServlet获得request对象就是封装之后的requestWapper对象
MyRequestWapper requestWapper = new MyRequestWapper((HttpServletRequest)request);
chain.doFilter(requestWapper, response);
} @Override
public void destroy() {
// TODO Auto-generated method stub } @Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub } }

我们来讲下思路:tomacat收到客户端的任何的request请求的时候,会将请求首先转交到

EncodingFilter 这个过滤器处理,会调用doFilter方法,在doFliter函数中,我们对原始的请求的request对象进行封装处理,对request对象中的getParameter()方法采用正确的编码方式。requestWapper就是封装之后的request对象,然后将requestWapper传递给servlet,sevlet中调用的
getParameter()获得的参数就是经过编码处理的参数。
我们来看看MyRequestWapper
package com.videos.utils;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; /*
* 这个类就是继承的经典例子:HttpServletRequestWrapper首先是request对象的包装类,实现了request对象的所有功能
* ,既然是request的封装类,内部肯定必须有一个等待包装的request对象,所有MyRequestWapper对象继承
* HttpServletRequestWrapper我们在构造函数中必须传递进来一个request对象。将request对象传输给父类HttpServletRequestWrapper使用super(request)就是传递给父类。
2 HttpServletRequestWrapper对象实现了request对象的所有方法,当然也实现了父类的getParameter(),
现在子类要对父类的getParameter()方法进行重写。在外面调用者调用的时候调用的是子类重写的方法,而不是父类的方法。
3 子类除了可以重写父类的方法之外,当然可以增加新的函数实现新的功能,所以本质上继承的主要目的是修改父类的功能和实现父类功能的扩展。
相当的经典。 3、 将封装之后的request对象wrapper传递给servlet,servlet本身获得wrapper对象就是一个封装的request对象,servlet调用wrapper对象的getPramas()获得的参数就是解决了中文乱码的。
4、 本质上就是过滤器对request对象进行封装处理,对getPatamets()函数进行重写,在重写的函数体里面采用正常的编码。将封装之后的wrapper对象传递给servlet对象使用,servlet对象调用的getPatamets()已经对乱码进行了处理,wrapper对象本质上就是servlet对象。 * */
public class MyRequestWapper extends HttpServletRequestWrapper{ private HttpServletRequest request;
public MyRequestWapper(HttpServletRequest request) {
super(request);
// TODO Auto-generated constructor stub
this.request = request; }
@Override
public String getParameter(String name) {
// TODO Auto-generated method stub
String value = request.getParameter(name);
if(value != null){
//对请求的参数采用正确的编码方式进行编码
try {
value = new String(value.getBytes("iso8859-1"),"utf-8"); return value;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} return super.getParameter(name);
} }

我们来分析下代码:

1、第一MyRequestWapper必须继承HttpServletRequestWrapper;

2、HttpServletRequestWrapper类也是对request类的封装类,实现了request对象的所有操作方法;

3、MyRequestWapper类的作用是对request对象的封装,所有构造函数中需要传人被封装的request对象,将request对象传输给父类HttpServletRequestWrapper使用super(request)就是传递给父类HttpServletRequestWrapper;

所有通过构造函数传递进来的request对象有两个作用:

(1)使用super(request)就是传递给父类HttpServletRequestWrapper,HttpServletRequestWrapper实现对request对象中函数的封装处理;

(2)request传递给MyRequestWapper调用,使用正确的编码对getParameter进行处理

4、HttpServletRequestWrapper对象实现了request对象的所有方法,当然也实现了request的getParameter(),现在子类MyRequestWapper要对HttpServletRequestWrapper父类的getParameter()方法进行重写使用正确的字符串编码。在外面调用者调用的时候调用的是子类MyRequestWapper重写的方法getParameter,而不是父类HttpServletRequestWrapper的方法getParameter。

上面就是继承的作用:

1、子类除了可以重写父类的方法之外修改原来的功能入上面的getParameter;

2、子类可以增加新的函数实现新的功能,实现父类功能的扩展。

接下来看看servlet的处理,这里没有就简单的将收到的参数打印到控制台上面,没有保存到数据库中:

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class ShowServlet
*/
@WebServlet("/ShowServlet")
public class ShowServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response); } /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String title = request.getParameter("title");
String timeLength = request.getParameter("timeLength");
System.out.println(title);
System.out.println(timeLength);
//在实际的开发过程中,这里得到参数之后,对参数进行校验,通过业务类操作接口将数据保存到数据库中
} }
Android客户端的代码:
客户端框架也是采用mvc的架构:
VideoService业务类:
package application.weiyuan.com.lihuoming_27.bussiness;

import android.util.Log;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map; /**
* Created by Administrator on 2017/4/19.
*/
public class VideoService { //采用get的方式提交参数
//http://localhost:8080/lihuoming_27/ShowServlet?title=中国&timeLenth=100
public static boolean submitByGet(String url, Map<String,String> params) throws IOException {
//对参数进行封装
StringBuilder builder = new StringBuilder(url);
builder.append("?");
//对params参数进行遍历
for(Map.Entry<String,String> entry: params.entrySet()){
builder.append(entry.getKey());
builder.append("=");
builder.append(URLEncoder.encode(entry.getValue(),"utf-8"));//对值进行URL中文编码
builder.append("&");
}
//把提交最好的一个"&"删除掉
builder.deleteCharAt(builder.length()-1); URL newURL = new URL(builder.toString());
HttpURLConnection connection = (HttpURLConnection)newURL.openConnection();
connection.setRequestMethod("GET");//必须是大写
connection.setConnectTimeout(5000);
connection.connect();
if(connection.getResponseCode() == 200){
Log.d("123456","get方式提交参数成功");
return true;
}
return false; } //采用post的方式提交参数
//http://localhost:8080/lihuoming_27/ShowServlet?title=中国&timeLenth=100
public static boolean submitByPost(String url, Map<String,String> params) throws IOException {
//对参数进行封装
StringBuilder builder = new StringBuilder();
//对params参数进行遍历
for(Map.Entry<String,String> entry: params.entrySet()){
builder.append(entry.getKey());
builder.append("=");
builder.append(URLEncoder.encode(entry.getValue(),"utf-8"));
builder.append("&");
}
//把提交最好的一个"&"删除掉
builder.deleteCharAt(builder.length()-1);
URL newURL = new URL(url);
HttpURLConnection connection = (HttpURLConnection)newURL.openConnection();
connection.setRequestMethod("POST");//必须是大写
connection.setConnectTimeout(5000);
connection.setDoOutput(true); //必须是true,运行向外输出数据,在消息体中提交参数
// 设置请求头的字段
connection.setRequestProperty("Content-Length", String.valueOf(builder.toString().length())); //内容的长度。该字段属性值必须有
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//内容提交的方式form是表单的形式,urlencoded表示以URL编码的方式
//post的提交必须转换成字节的形式,默认是UTF-8的形式
byte[] data = builder.toString().getBytes();
OutputStream outputStream = connection.getOutputStream();
outputStream.write(data); connection.connect();
if(connection.getResponseCode() == 200){
Log.d("123456","get方式提交参数成功");
return true;
}
return false; }
}

我们来看看activity

package application.weiyuan.com.lihuoming_27;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import application.weiyuan.com.lihuoming_27.bussiness.VideoService; public class MainActivity extends Activity { private Button btn_main_post;
private Button btn_main_get;
private EditText et_main_length;
private EditText et_main_title;
private ExecutorService executorService; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
} private void initListener() {
btn_main_get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
executorService = Executors.newCachedThreadPool();
executorService.execute(new Runnable() {
@Override
public void run() {
String title = et_main_title.getText().toString();
String timeLength = et_main_length.getText().toString();
if(TextUtils.isEmpty(timeLength) || TextUtils.isEmpty(title)){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"标题时间长度不为空",Toast.LENGTH_LONG).show();
return;
}
});
} String url = "http://10.12.8.13:8080/lihuoming_27/ShowServlet";
Map<String,String> map = new HashMap<String, String>();
map.put("title",title);
map.put("timeLength",timeLength);
try {
boolean flag = VideoService.submitByGet(url, map);
if(flag){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"Get提交参数成功",Toast.LENGTH_LONG).show();
return;
}
});
} } catch (final IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"Get提交参数失败"+e.toString(),Toast.LENGTH_LONG).show();
return;
}
});
}
}
});
}
}); btn_main_post.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
executorService = Executors.newCachedThreadPool();
executorService.execute(new Runnable() {
@Override
public void run() {
String title = et_main_title.getText().toString();
String timeLength = et_main_length.getText().toString();
if(TextUtils.isEmpty(timeLength) || TextUtils.isEmpty(title)){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"标题时间长度不为空",Toast.LENGTH_LONG).show();
return;
}
});
} String url = "http://10.12.8.13:8080/lihuoming_27/ShowServlet";
Map<String,String> map = new HashMap<String, String>();
map.put("title",title);
map.put("timeLength",timeLength);
try {
boolean flag = VideoService.submitByPost(url, map);
if(flag){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"post提交参数成功",Toast.LENGTH_LONG).show();
return;
}
});
} } catch (final IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"post提交参数失败"+e.toString(),Toast.LENGTH_LONG).show();
return;
}
});
}
}
});
}
});
} private void initView() {
et_main_length = (EditText) findViewById(R.id.et_main_length);
et_main_title = (EditText) findViewById(R.id.et_main_title);
btn_main_get = (Button) findViewById(R.id.btn_main_get);
btn_main_post = (Button) findViewById(R.id.btn_main_post);
}
}

我们来看看xml文件

<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="application.weiyuan.com.lihuoming_27.MainActivity"> <TextView
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="视频名称" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:id="@+id/et_main_title"/>
<TextView
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="视频长度" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:id="@+id/et_main_length"/>
<Button
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="get方式提交"
android:id="@+id/btn_main_get"/>
<Button
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="post方式提交"
android:id="@+id/btn_main_post"/>
</LinearLayout>
 

黎活明8天快速掌握android视频教程--27_网络通信之通过GET和POST方式提交参数给web应用的更多相关文章

  1. 黎活明8天快速掌握android视频教程--25_网络通信之资讯客户端

    1 该项目的主要功能是:后台通过xml或者json格式返回后台的视频资讯,然后Android客户端界面显示出来 首先后台新建立一个java web后台 采用mvc的框架 所以的servlet都放在se ...

  2. 黎活明8天快速掌握android视频教程--24_网络通信之网页源码查看器

    1 该项目的主要功能就是从将后台的html网页在Android的界面上显示出来 后台就是建立一个java web工程在工程尚建立一个html或者jsp文件就可以了,这里主要看Android客户端的程序 ...

  3. 黎活明8天快速掌握android视频教程--23_网络通信之网络图片查看器

    1.首先新建立一个java web项目的工程.使用的是myeclipe开发软件 图片的下载路径是http://192.168.1.103:8080/lihuoming_23/3.png 当前手机和电脑 ...

  4. 黎活明8天快速掌握android视频教程--22_访问通信录中的联系人和添加联系人

    Android系统中联系人的通讯录的contentProvide是一个单独的apk,显示在界面的contact也是一个独立的apk,联系人apk通过contentProvide访问底层的数据库. 现在 ...

  5. 黎活明8天快速掌握android视频教程--21_监听ContentProvider中数据的变化

    采用ContentProvider除了可以让其他应用访问当前的app的数据之外,还有可以实现当app的数据发送变化的时候,通知注册了数据变化通知的调用者 其他所有的代码都和第20讲的一样,不同的地方看 ...

  6. 黎活明8天快速掌握android视频教程--20_采用ContentProvider对外共享数据

    1.内容提供者是让当前的app的数据可以让其他应用访问,其他应该可以通过内容提供者访问当前app的数据库 contentProvider的主要目的是提供一个开发的接口,让其他的应该能够访问当前应用的数 ...

  7. 黎活明8天快速掌握android视频教程--19_采用ListView实现数据列表显示

    1.首先整个程序也是采用mvc的框架 DbOpenHelper 类 package dB; import android.content.Context; import android.databas ...

  8. 黎活明8天快速掌握android视频教程--17_创建数据库与完成数据添删改查

    1.我们首先来看下整个项目 项目也是采用mvc的框架 package dB; import android.content.Context; import android.database.sqlit ...

  9. 黎活明8天快速掌握android视频教程--16_采用SharedPreferences保存用户偏好设置参数

    SharedPreferences保存的数据是xml格式,也是存在数据保存的下面四种权限: 我们来看看 我们来看看具体的业务操作类: /** * 文件名:SharedPrecences.java * ...

随机推荐

  1. Vue 哈希换histroy

    这个需要后端支持一下 前端配置在router下的index.js配置如下: import Vue from 'vue' import Router from 'vue-router' import I ...

  2. Asp.Net Mvc基于Fleck开发的多人网页版即时聊天室

    一.项目的核心说明 1.Fleck这个是实现websocket一个比较简单第三方组件,它不需要安装额外的容器.本身也就几个接口可供调用. 2.项目是基于.net framework 4.7.2 ,在v ...

  3. .net core 上传大文件

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Thr ...

  4. Rocket - debug - TLDebugModuleInner - Abstract Command Decoding & Generation

    https://mp.weixin.qq.com/s/0zKSTktxgzo5uCUphqaWSQ 介绍抽象命令的解码和生成. 1. accessRegisterCommandReg accessRe ...

  5. Verilog缺少一个复合数据类型,如C语言中的结构体

    https://mp.weixin.qq.com/s/_9UsgUQv-MfLe8nS938cfQ Verilog中的数据类型(Data Type)是分散的,缺少一个复合数据类型:把多个wire, r ...

  6. Linux (七)权限控制

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1. 概述 Linux需要对登录用户读写执行文件.进入目录.查看增删目录内容等操作进行控制,不能任由用户 ...

  7. (Java实现) 图的m着色问题

    图的m着色问题 [问题描述] 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色.如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的.图的m着色问 ...

  8. java实现低碳生活大奖赛

    某电视台举办了低碳生活大奖赛.题目的计分规则相当奇怪: 每位选手需要回答 10 个问题(其编号为 1 到 10),越后面越有难度. 答对的,当前分数翻倍:答错了则扣掉与题号相同的分数(选手必须回答问题 ...

  9. java实现第三届蓝桥杯古代赌局

    古代赌局 [编程题](满分23分) 俗话说:十赌九输.因为大多数赌局的背后都藏有阴谋.不过也不尽然,有些赌局背后藏有的是:"阳谋". 有一种赌局是这样的:桌子上放六个匣子,编号是1 ...

  10. Liunx常用运维命令整理记录

    前言 作为后端开发者,掌握一些常用的运维命令也是很有必要的,本文记录常用Liunx运维命令 基本命令 目录切换 cd base-admin/ 切换到当前目录下的base-admin目录 cd .. 切 ...