问题描写叙述

当我们使用SpringMVC作为服务端的框架时,有时不仅仅要应对web前端(jsp、javascript、Jquery等)的訪问请求,有时还可能须要响应Android和JavaSE(桌面应用)这些client的请求。因此,除了web使用form表单或者ajax作为client获取Controller响应之外。纯Java语言向SpringMVC的Controller提供參数和请求结果也是必须要实现的。web前端使用form和ajax来获取Controller响应在本篇博客暂不深究,本篇博课着力于实现纯Javaclient来实现请求Controller并获取响应。(假设不想看以下的方法探索,能够直接跳到第三部分)

方法探索

确定了须要解决的问题之后。我開始搜索相关的博客和问答。发现这样的问题相关解决方法不是非常多,找了非常多博客都是牛头不正确马嘴,可是还是有一些对解决这个问题有帮助的内容,之后又翻了非常久的书,对这个问题的解决方法有了主要的认识。

    看网上说的行之有效的方法是使用HttpClient来实现这个功能,只是须要导入HttpClient和HttpCore两个jar包。当时研究了一下认为可行。

可是在实际操作过程中。在向Android(IDE:Android Studio)build.gradle里面导入上述两个jar包的依赖后,同步的时候Android Studio给出了两个警告,大意是HttpClient已经过期云云。然后我又专门去查了一个HttpClient这个东西和Android之间的关系,发现Android6.0以及之后的版本号放弃了对HttpClient的支持。强行导入jar包也不行。(据说有人用了非常麻烦的方法导入成功过 = =)那好嘞。不让用算了。那就不用呗。看參考书《疯狂Android讲义》对HttpClient还那么推崇。也是有点醉。

详细不让用的原因就不再深究了,接下来就研究使用HttpUrlConnection来解决上述问题吧。

在使用HttpURLConnection的过程中代码实现照着套路来问题不大。遇到的问题是SpringMVC的Controller怎么接收数据,接收的数据格式是什么?我应该传什么类型的数据?

    Controller怎么接收数据这个问题经过前段时间的学习我已经有个大概的认识,SpringMVC的Controller工作原理就是client向 项目地址+Controller前面的value值 这个url发出请求,这个请求会带有一些參数。而SpringMVC会将请求携带的參数转换为Controller相应value以下的方法的參数,然后在这种方法进行相关的操作再返回client一些參数,至于返回的结果就有几种可能了。假设上面没有@ResponseBody凝视,返回的数据有可能是jsp页面的名字,则web会跳转到相应的jsp页面假设是ModelAndView也会跳转到相应的页面而假设加上@ResponseBody。那么返回的就是json类型的数据了,client会接收到Controller返回的參数。那么,明确了springmvc的工作原理,那么怎么使用HttpUrlConnection来訪问Controller就大概清楚了:我们就把请求地址拼接好,然后把携带的数据发送过去就能够等着拿到Controller返回的数据了。

那么第二个问题就来了。请求的地址清楚了。携带的数据应该是什么格式的呢?

    刚開始我以为和返回值一样是Json格式的键值对形式,比方说用户登录的userName和userPassword,(Controller的參数形式为 doLogin(String userName,String userPassword))開始我以为应该发送json格式数据。可是服务端不鸟我,没有获得參数。后来我又试了jsonArray形式也不行,试了map的键值对形式不行。我就疑惑了究竟是什么形式的。最后找了半天看了ajax发出相同请求时的http报文结构才知道了数据格式是什么样子的。

是这样的:

中间是一个&连接了两个參数,键值中间是=,好吧,最终明确了。当然这是Controller參数为两个单独的String值的时候的类型,有一种更好的办法是直接把Controller的參数设置为一个,然后在Controller里面解析Json数据,这样事实上更方便一点,以后还更easy做加密工作,只是眼下改起来太麻烦就不改了吧。如今弄明确了controller是两个參数的时候是这样的结构的。至于其他的list。bean以及json类型这里就不探究了。由于我看到非常多别的博主都讲了怎么转了。

废话了这么多。以下放代码。

解决这个问题

SpringMVC相应Controller代码(result单词拼错了,懒得改咯):

  1. @RequestMapping(value="/doLogin",method=RequestMethod.POST)
  2. @ResponseBody
  3. public Map<String,Object> doLogin(String userName,String userPassword,HttpSession httpSession){
  4. String resoult="fail";
  5. User user = userService.getUser(userName);
  6. UserDetail userDetail = userDetailService.getUserDetail(userName);
  7. if(user!=null){
  8. if(Objects.equals(userDetail.getUserDetailPassword(), userPassword)){
  9. httpSession.setAttribute("currentUser",user);
  10. resoult = "success";
  11. }
  12. else{
  13. resoult = "wrong";
  14. }
  15. }
  16. else{
  17. resoult = "unexist";
  18. }
  19. Map<String, Object> resoults = new HashMap<String,Object>();
  20. resoults.put("resoult", resoult);
  21. return resoults;
  22. }

Android端或者java端写的一个HttpPostUtils工具类

  1. package cn.justwithme.withme.Utils;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.HttpURLConnection;
  7. import java.net.MalformedURLException;
  8. import java.net.URL;
  9. /**
  10. * Created by 桐木木 on 2017/2/8.
  11. * 发送Http请求。获取Controller返回的数据
  12. *
  13. */
  14. public class HttpPostUtils {
  15. public static String doPostRequest(String path,Object content){
  16. PrintWriter out = null;
  17. BufferedReader in = null;
  18. String resoult = "";
  19. try {
  20. System.out.println("要发送的信息是:"+content);
  21. /*拼接url,Android这里须要换上远程地址,由于Android端没办法訪问localhost。java的话本地tomcat执行的话倒是无妨*/
  22. String address = http://localhost:8080/WithMe/"+path;
  23. URL url = new URL(address);
  24. HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
  25. //这两个參数必须加
  26. httpURLConnection.setDoInput(true);
  27. httpURLConnection.setDoOutput(true);
  28. //设置超时时间
  29. httpURLConnection.setReadTimeout(10*1000);
  30. httpURLConnection.setConnectTimeout(10*1000);
  31. httpURLConnection.setRequestMethod("POST");
  32. httpURLConnection.connect();
  33. out = new PrintWriter(httpURLConnection.getOutputStream());
  34. //在输出流中写入參数
  35. out.print(content);
  36. out.flush();
  37. if(httpURLConnection.getResponseCode() == 200){
  38. in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8"));
  39. String line;
  40. while((line=in.readLine())!=null){
  41. resoult+=line;
  42. }
  43. }
  44. System.out.println("server返回的结果是:"+resoult);
  45. return resoult;
  46. } catch (MalformedURLException e) {
  47. System.out.println("URL异常");
  48. e.printStackTrace();
  49. } catch (IOException e) {
  50. System.out.println("IO异常");
  51. e.printStackTrace();
  52. }finally {
  53. try{
  54. if(out!=null)
  55. out.close();
  56. if(in!=null)
  57. in.close();
  58. }catch (IOException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. return null;
  63. }
  64. }

工具类写好之后我们分别在Android端和Java端进行一些測试,(在我的服务端我已经注冊过14121047的前提下,你假设仅仅是測试把服务端查询数据库校验密码改成字符串匹配就成了)。

Android

LoginActivity.java

  1. package cn.justwithme.withme.Activity;
  2. import android.os.Bundle;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.support.v7.app.AppCompatActivity;
  6. import android.view.View;
  7. import android.widget.Button;
  8. import android.widget.EditText;
  9. import com.alibaba.fastjson.JSON;
  10. import com.alibaba.fastjson.JSONObject;
  11. import java.util.HashMap;
  12. import java.util.Map;
  13. import cn.justwithme.withme.R;
  14. import cn.justwithme.withme.Utils.HttpPostUtils;
  15. public class LoginActivity extends AppCompatActivity {
  16. private String result;
  17. private Handler mHanlder = new Handler() {
  18. @Override
  19. public void handleMessage(Message message) {
  20. result = (String) message.obj;
  21. JSONObject resultJson = JSON.parseObject(result);
  22. String finalResult = resultJson.getString("resoult");
  23. System.out.println("结果是:"+finalResult);
  24. if(finalResult.equals("success")){
  25. System.out.println("登陆成功");
  26. }
  27. else
  28. System.out.println("username或密码错误");
  29. }
  30. };
  31. @Override
  32. protected void onCreate(Bundle savedInstanceState) {
  33. super.onCreate(savedInstanceState);
  34. setContentView(R.layout.activity_login);
  35. final EditText userNameInput = (EditText)findViewById(R.id.userName);
  36. final EditText passwordInput = (EditText)findViewById(R.id.password);
  37. Button login = (Button)findViewById(R.id.login);
  38. login.setOnClickListener(new View.OnClickListener() {
  39. @Override
  40. public void onClick(View v) {
  41. String userName = userNameInput.getText().toString();
  42. String userPassword = passwordInput.getText().toString();
  43. final Map<String,Object> userInfo = new HashMap<String,Object>();
  44. userInfo.put("userName",userName);
  45. userInfo.put("userPassword",userPassword);
  46. // UserLogin userInfo = new UserLogin();
  47. // userInfo.setUserName(userName);
  48. // userInfo.setUserPassword(userPassword);
  49. final String user = "userName="+userName+"&userPassword="+userPassword;
  50. if(userName!= null && !userName.equals("") && userPassword!=null && !userPassword.equals("")){
  51. /*这里须要留意的是httpPostUtils请求在Android里面不能放在主线程里面,必须新建一个子线程。然后通过Hanlder把子线程的值传过来更新UI(由于子线程不能直接更改UI)*/
  52. new Thread() {
  53. public void run() {
  54. String response = HttpPostUtils.doPostRequest("doLogin",user);
  55. Message message = Message.obtain();
  56. message.obj = response;
  57. mHanlder.sendMessage(message);
  58. }
  59. }.start();
  60. }
  61. else{
  62. System.out.println("username密码不能为空");
  63. }
  64. }
  65. });
  66. }
  67. }

好吧。这是非常简陋的代码,毕竟Androidclient才刚刚開始写,activity_login.xml就不放了,两个输入框一个button而已。能够再以下查看输出结果来推断功能是否实现:

以下是Java的測试代码,用的工具类和Android用的一样的。

  1. package httpPost;
  2. public class test {
  3. public static void main(String[] args){
  4. String test = "userName=14121047&userPassword=14121047";
  5. String ans = HttpPostUtils.doPostRequest("doLogin", test);
  6. System.out.println("server返回的数据为:"+ans);
  7. }
  8. }

測试结果为:

  1. 要发送的信息是:userName=14121047&userPassword=14121047
  2. server返回的结果是:{"resoult":"success"}
  3. server返回的数据为:{"resoult":"success"}

结束语

当然,我这里演示的知识一个非常简单的android和java向springmvc发送请求的样例,可是,既然中间的道理和方法明确了,那之后不管是什么格式的数据都不是非常难了。

Json数据的那仅仅用一个參数就好了咯,两个參数都传了一个參数不是非常easy么?要传bean的先把Bean转json到服务端再把json转bean就好了咯。233。。

。(这里仅仅是讨论一下两个參数怎么传。并非不想用json。



    好好学习,天天向上,加油!

Android(或者Java)通过HttpUrlConnection向SpringMVC请求数据(数据绑定)的更多相关文章

  1. Java 利用HttpURLConnection发送http请求

    写了一个简单的 Http 请求的Class,实现了 get, post ,postfile package com.asus.uts.util; import org.json.JSONExcepti ...

  2. Android开发之使用HttpURLConnection进行POST请求

    一.前提准备 在开始实际编码之前,我们有必要先了解下将会用的类以及方法,进行一个大体的了解. 1.URL类 这个类主要的功能是定位到要获取资源的网址以及打开连接.比如下面的代码: URL realur ...

  3. Java利用原始HttpURLConnection发送http请求数据小结

    1,在post请求下,写输出应该在读取之后,否则会抛出异常. 即操作OutputStream对象应该在InputStreamReader之前. 2.conn.getResponseCode()获取返回 ...

  4. springmvc请求数据的流程。

    验证了我说的,从model层中拿来的数据,不管什么类型,都是通过隐含模型,中转,放入request中的.除非你特意把这些数据放到session域中 流程含义解释:(来自网友)(1)HTTP请求到达we ...

  5. HttpURLConnection 发送http请求帮助类

    java 利用HttpURLConnection 发送http请求 提供GET / POST /上传文件/下载文件 功能 import java.io.*; import java.net.*; im ...

  6. Java中HttpURLConnection使用详解、总结。

    感谢大佬:https://blog.csdn.net/qq_40036754/article/details/102554755 文章目录 一.前言 二.HttpURLConnection 介绍 三. ...

  7. Android(java)学习笔记210:采用post请求提交数据到服务器(qq登录案例)

    1.POST请求:  数据是以流的方式写给服务器 优点:(1)比较安全 (2)长度不限制 缺点:编写代码比较麻烦   2.我们首先在电脑模拟下POST请求访问服务器的场景: 我们修改之前编写的logi ...

  8. Android(java)学习笔记209:采用get请求提交数据到服务器(qq登录案例)

    1.GET请求:    组拼url的路径,把提交的数据拼装url的后面,提交给服务器. 缺点:(1)安全性(Android下提交数据组拼隐藏在代码中,不存在安全问题)  (2)长度有限不能超过4K(h ...

  9. Android(java)学习笔记153:采用post请求提交数据到服务器(qq登录案例)

    1.POST请求:  数据是以流的方式写给服务器 优点:(1)比较安全 (2)长度不限制 缺点:编写代码比较麻烦   2.我们首先在电脑模拟下POST请求访问服务器的场景: 我们修改之前编写的logi ...

随机推荐

  1. 再论FreeRTOS中的configTOTAL_HEAP_SIZE

    关于任务栈和系统栈的基础知识,可以参考之前的随笔.(点击这里) 这里再次说明:#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) 这个 ...

  2. php 找出异常发生的地方

    多层嵌套发生异常,找到异常最早发生的地方. final public int Exception::getLine ( void ) final public string Exception::ge ...

  3. Android NFC近场通信2——NFC标签调度

    上面一篇文章简单介绍了NFC的背景和技术应用,今天主要是讲解一下NFC如何发起通信和标签通信(主要是翻译android官网的资料,中间加入个人心得). NFC总是在一个发起者和一个被动目标之间发生.发 ...

  4. bootstrapTable刷新当前页码不变和从第一页开始查询

    function searchAgencyProject(){ $("#statisticalProjectListTable").bootstrapTable('refresh' ...

  5. zookeeper学习:知识点收集

    其实学习zookeeper挺简单的,找一本书或者网上的资源,按照其中的例子做一遍就大致了解了.之前是自己学习的方法有问题. 1. 会启动单机版的服务器,并使用客户端连接,然后进行节点的各种操作 2. ...

  6. 网页QQ弹出

    <script language="javascript"> function cdyht(){ window.location.href='tencent://Mes ...

  7. 【C】——setvbuf(scanf内存溢出问题)

    下面设置了一个长度为20的缓存区,循环对value进行赋值并输出: #include<stdio.h> #define BUFSIZE 20 int main(int argc, char ...

  8. MFC函数——CWnd::OnCreate

    CWnd::OnCreate afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); 返回值: OnCreate必须返回0以继续CWnd对象的创建 ...

  9. maven启动项目时报错

    java.lang.UnsupportedClassVersionError eclipse中使用maven插件的时候,运行run as maven build的时候报错 -Dmaven.multiM ...

  10. 微信小程序——网盘图片预览

    微信小程序图片预览提供了一个wx.previewImage接口,如下图: 现在我需要对网盘文件里的图片预览,但是网盘从后台返回的数据是各种类型的文件,如下图所示: 那么我们需要解决2个问题: 1.从这 ...