Android客户端连接SSM(Spring+SpringMVC+Mybatis)框架Java服务器端

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yanweju/article/details/70861659

Android客户端开发越来越流行,但是,Android客户端对应的服务器端采用什么框架呢?对于功能较为简单的应用,我建议,直接采用java web开发最简单的MVC框架即可(很多Android应用的服务器端开发框架,我都是采用这种);但是,对于功能较为复杂,数据库表较多,逻辑关系比较复杂的应用开发,服务器端逻辑关系自然也是一样,我们是否可以考虑采用java web开发流行的SSH2/SSM等框架呢?经过实践测试,我将Android客户端连接SSM ( Spring + SpingMVC + Mybatis)框架java web服务器端的开发模式,详细给大家细细介绍一下吧~

其中,这里需要介绍的是,java web服务器端不只是需要处理来自Android客户端的请求,而且,同时需要处理来自后台管理系统(使用jsp开发前台页面)的请求,因此,在编写请求接受和处理函数时,需要分别编写(这里,我采用的是分别编写各自的处理函数)。

1.开发Android应用客户端

整个的Android客户端(TestSSMServer)的框架结构:
这里写图片描述

1.1 activity

MainActivity.java

package com.ju.testssmserver.activity;

import com.ju.testssmserver.R;
import com.ju.testssmserver.R.id;
import com.ju.testssmserver.R.layout;
import com.ju.testssmserver.R.menu;
import com.ju.testssmserver.model.UserInfoModel;
import com.ju.testssmserver.object.User;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView userIDTV;
    private TextView userNameTV;
    private TextView passwordTV;
    private Button getBtn;

    private Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        userIDTV = (TextView) findViewById(R.id.userIDTV);
        userNameTV = (TextView) findViewById(R.id.userNameTV);
        passwordTV = (TextView) findViewById(R.id.passwordTV);
        getBtn = (Button)findViewById(R.id.getBtn);

        intent= this.getIntent();

        getBtn.setOnClickListener(new OnClickListener() 
        {
            @Override
            public void onClick(View v) {
                initActivity();

            }
        });

    }

    private void initActivity(){
        /**
         * Handler
         * @note 用于子线程和主线程之间的数据传递
         * 解决了andr4.0以上主线程无法访问网络的问题。
         */
        final Handler myhandler = new Handler() {
            public void handleMessage(Message msg) {
                //isNetError = msg.getData().getBoolean("isNetError");
                if(msg.what==0x123)
                {
                    userIDTV.setText(String.valueOf(msg.getData().getInt("userID")));
                    userNameTV.setText(msg.getData().getString("userName"));
                    passwordTV.setText(msg.getData().getString("password"));
                }
            }
        };

        /**
         * 新建子线程
         * @note 用于建立网络连接,从服务器获取IMEI对应的用户信息
         * 解决了andr4.0以上主线程无法访问网络的问题。
         */
        new Thread(){
            public void run(){
                UserInfoModel userInfoModel = new UserInfoModel();      
                User user = new User();

                try {
                    user = userInfoModel.getUserInfo(2);

                    if(user == null)
                    {
                        myhandler.post(new Runnable(){
                                public void run(){
                                showDialog("数据库中未查找到你的相关信息!请及时注册!");
                                }
                        });
                    }
                    else
                    {
                        Bundle bundle = new Bundle();       
                        Message message = new Message();

                        bundle.putInt("userID", user.getUserID());
                        bundle.putString("userName", user.getUserName());
                        bundle.putString("password", user.getPassword());

                        message.setData(bundle);
                        message.what=0x123;         
                        myhandler.sendMessage(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }


    /**
     * 对话框显示函数
     * 
     * @param message是要显示的内容
     */
    private void showDialog(String message) {
        AlertDialog.Builder builder = new AlertDialog.Builder(
                MainActivity.this);
        builder.setMessage(message);

        builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                MainActivity.this.setResult(RESULT_OK, intent);
                MainActivity.this.finish();  
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

对应的layout ——activity_main.xml的代码:

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.ju.testssmserver.activity.MainActivity" >

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="26dp"
        android:layout_marginTop="50dp" >

       <TableRow
            android:id="@+id/tableRow5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
            <Button
                android:id="@+id/getBtn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center|center_horizontal"
                android:gravity="center|center_vertical"
                android:text="Get信息"
                android:textAppearance="@style/labelText"/>
        </TableRow>
        <TableRow
            android:id="@+id/tableRow4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/textView0"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center|center_horizontal"
                android:gravity="center|center_vertical"
                android:text="登录信息"
                android:textAppearance="@style/labelText" />          

        </TableRow>

        <TableRow
            android:id="@+id/tableRow1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/textView1"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_weight="0.5"
                android:gravity="center_vertical"
                android:text="用\t户\tID:"
                android:textAppearance="@style/labelText" />

            <TextView
                android:id="@+id/userIDTV"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_marginRight="30dp"
                android:layout_weight="0.5"
                android:gravity="right|center_vertical"
                android:text=""
                android:textAppearance="@style/normalText" />
        </TableRow>

        <TableRow
            android:id="@+id/tableRow2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/textView2"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_weight="0.5"
                android:gravity="center_vertical"
                android:text="用\t户\t名:"
                android:textAppearance="@style/labelText" />

            <TextView
                android:id="@+id/userNameTV"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_marginRight="30dp"
                android:layout_weight="0.5"
                android:gravity="right|center_vertical"
                android:text=""
                android:textAppearance="@style/normalText" />            
        </TableRow>

        <TableRow
            android:id="@+id/tableRow3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/textView3"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_weight="0.5"
                android:gravity="center_vertical"
                android:text="密\t\t\t码:"
                android:textAppearance="@style/labelText" />

            <TextView
                android:id="@+id/passwordTV"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_marginRight="30dp"
                android:layout_weight="0.5"
                android:gravity="right|center_vertical"
                android:text=""
                android:textAppearance="@style/normalText" />            
        </TableRow>

    </TableLayout>

</RelativeLayout>

1.2 object

User.java

/**
 * 
 */
package com.ju.testssmserver.object;

/**
 * @author Yan Wenju
 *
 */
public class User {

    private int userID;
    private String userName;
    private String password;

    public int getUserID(){
        return userID;
    }
    public void setUserID(int id){
        this.userID = id;
    }

    public String getUserName(){
        return userName;
    }
    public void setUserName(String userName){
        this.userName = userName;
    }

    public String getPassword(){
        return password;
    }
    public void setPassword(String password){
        this.password = password;
    }
}

1.3 model

UserInfoModel .java

/**
 * 
 */
package com.ju.testssmserver.model;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

import com.ju.testssmserver.config.ServerConfiguration;
import com.ju.testssmserver.object.User;

import android.util.Log;

/**
 * @author Yan Wenju
 *
 */
public class UserInfoModel {

    /**
     * 获取用户详细信息
     * 
     */
    public User getUserInfo(int userID) throws Exception 
    {
        User user = null;
        HttpClient httpclient = new DefaultHttpClient();
        List<NameValuePair> qparams = new ArrayList<NameValuePair>();
        //qparams.add(new BasicNameValuePair("method", "getDetail"));
        qparams.add(new BasicNameValuePair("id",String.valueOf(userID)));
        URI uri = URIUtils.createURI("http", ServerConfiguration.IP,
                ServerConfiguration.PORT,
                ServerConfiguration.USERSERVICEURI,
                URLEncodedUtils.format(qparams, "UTF-8"), null);
        Log.i("ju", "uri:"+uri.toString());
        HttpGet httpget = new HttpGet(uri);
        //HttpPost httpget=new HttpPost(uri);
        HttpResponse response = httpclient.execute(httpget);
        HttpEntity entity = response.getEntity();
        JSONObject o = null;
        if (entity != null) 
        {
            String contentString = EntityUtils.toString(entity);
            Log.i("ju", contentString);
            o = new JSONObject(contentString);      
            int status =o.getInt("status");
            Log.i("ju","status:"+ status);

            if (status != 1) 
            {
                Log.i("ju","status:"+ status);
                return user;
            }

            JSONObject e = o.getJSONObject("user");
            user = new User();

            user.setUserID(e.getInt("id"));
            user.setUserName(e.getString("userName"));
            user.setPassword(e.getString("password"));
        }

        httpclient.getConnectionManager().shutdown();
        return user;
    }

}

1.4 config

ServerConfiguration .java

package  com.ju.testssmserver.config;

/**
 * Author YanWenju
 * 这是客服端与服务器端通信的配置信息。
 */

public class ServerConfiguration 
{
    public static final String IP = "192.168.0.108";//服务器地址
    public static final int PORT = 8088;//要根据应用服务器tomcat的端口改变
    public static final String USERSERVICEURI = "testSSM/test/getInfo.json";
}

2.搭建SSM服务器端框架

SSM框架结构搭建在网上很多,不过,因为需要与Android客户端进行数据交换(我采用的是json格式),所以,在配置文件时,稍有不同。重点对不同之处进行介绍。
Java web SSM框架结构如下:

这里写图片描述

2.1 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>Archetype Created Web Application</display-name>
    <!-- Spring和mybatis的配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- spring-mybatis.xml类似于之前的applicationContext.xml -->
        <param-value>classpath:spring-mybatis.xml</param-value>
    </context-param>

    <!-- 编码过滤器 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Spring监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 防止Spring内存溢出监听器 -->
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>

    <!-- Spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <!-- 此处配置成*.do,对应struts的后缀习惯 -->
        <url-pattern>*.do</url-pattern>
        <!-- 此处配置成*.json,是为了能够截获"../*.json"格式的访问(例如android客户端) -->
        <url-pattern>*.json</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>
    <!-- 配置SESSION超时,单位是分钟 -->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

</web-app>

解析:
web.xml文件配置,最大的不同在于:DispatcherServlet截获的url格式,添加了一种——*.json,用于区别请求是来自Android客户端还是浏览器的jsp前台页面。

2.2 spring-mvc.xml(即DispatcherServlet前端处理器配置文件)

spring-mvc.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
                        http://www.springframework.org/schema/context  
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd  
                        http://www.springframework.org/schema/mvc  
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
    <context:component-scan base-package="com.testSSM.test.controller" />

        <!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
    <bean id="multipartResolver"       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <!-- 默认编码 -->
        <property name="defaultEncoding" value="utf-8" />  
        <!-- 文件大小最大值 -->
        <property name="maxUploadSize" value="10485760000" />  
        <!-- 内存中的最大值 -->
        <property name="maxInMemorySize" value="40960" />  
    </bean> 
</beans>

解析:
这里没有特殊需要配置的地方。

2.3 spring-mybatis.xml

接下来,是配置spring容器和mybatis的各种变量(dataSource、SqlSessionFactoryBean、MapperScannerConfigurer、transactionManager等):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
                        http://www.springframework.org/schema/context  
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd  
                        http://www.springframework.org/schema/mvc  
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 自动扫描 -->
    <context:component-scan base-package="com.testSSM.test" />
    <!-- 引入配置文件 -->
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:jdbc.properties" />
    </bean>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
        init-method="init" destroy-method="close">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${initialSize}"></property>
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${maxActive}"></property>
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${maxIdle}"></property>
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${minIdle}"></property>
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${maxWait}"></property>
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath:com/testSSM/test/mapping/*.xml"></property>
    </bean>

    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.testSSM.test.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

2.4 jdbc.properties

jdbc.properties是存储mybatis各项设置参数的文件(与hibernate等基本相似):

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/testssm?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
username=root
password=123456
#定义初始连接数
initialSize=0
#定义最大连接数
maxActive=20
#定义最大空闲
maxIdle=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

3.控制器处理函数(controller.java)

Android客户端连接SSM框架服务器端,最关键的问题就在于:如何编写控制器以及相关请求处理函数。
下面,我以“用户登录信息”的增改删查为例,具体函数的编写,请看代码:

3.1 实例代码

控制器controller.java源代码:

package com.testSSM.test.controller;

import java.io.PrintWriter;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testSSM.test.model.User;
import com.testSSM.test.service.TestService;
import net.sf.json.JSONObject;


@Controller
@RequestMapping("/test")
public class TestController {

    @Resource
    private TestService testService;

    //--------------------添加新用户信息 Start-----------------------
    //访问添加用户信息页面
    @RequestMapping("/addPage.do")
    public String addPage(){
        return "add";
    }
    //处理来自jsp页面的请求,并切换到结果页面
    @RequestMapping("/addUser.do")
    public String addUserFromJspPage(HttpServletRequest request, Model model, @RequestParam("userName") String userName,@RequestParam("password") String password){
/*      第二种获取jsp前台页面传递值的方式:
        String userName=request.getParameter("userName");
        String password=request.getParameter("password");*/
        User user = new User();
        user.setUserName(userName);
        user.setPassword(password);

        try{
            if(testService.add(user)==true){
                model.addAttribute("result", "添加成功了!");
                return "success";
            }else{
                model.addAttribute("result", "添加失败了!");
                return "failure";
            }
        } catch(Exception e){
            model.addAttribute("result", e.toString());
            return "failure";
        }

    }
    //处理来自客户端的请求,并将json格式的数据处理结果返回。
    @RequestMapping("/addUser.json")
    public void addUserFromClient(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("userName") String userName,@RequestParam("password") String password){
/*      第二种获取android客户端传递值的方式:
        String userName=request.getParameter("userName");
        String password=request.getParameter("password");*/
        User user = new User();
        user.setUserName(userName);
        user.setPassword(password);

        response.setContentType("application/json");
        PrintWriter out = null;
        JSONObject json = new JSONObject();

        try{
            out = response.getWriter();

            if(testService.add(user)==true){
                json.put("status", 1);
                out.write(json.toString());
            }else{
                json.put("status", 0);
                out.write(json.toString());
            }
        } catch(Exception e){
            e.printStackTrace();
            json.put("status", -1);
            out.write(json.toString());
        }finally{
            out.flush();
            out.close();
        }

    }
    //--------------------添加新用户信息 End-----------------------

    //--------------------查询单个用户信息 Start-----------------------
    //访问查询页面"query.jsp"
    @RequestMapping("/queryPage.do")
    public String queryPage(){
        return "query";
    }
    //处理浏览器的获取单个用户信息请求,页面切换到查询结果页面queryResult.jsp
    @RequestMapping("/getInfo.do")
    public String getInfoFromJspPage(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("id") int id) {

        User user = new User();
        user.setId(id);

        try {           
            user = testService.queryByID(user);
            if (user != null) {
                model.addAttribute("user", user);

            } else {
                model.addAttribute("user", null);               
            }
        } catch (Exception e) {
            e.toString();
        }

        return "queryResult";
    }
    //处理客户端单个用户信息请求,返回json格式请求查询数据
    @RequestMapping("/getInfo.json")
    public void getInfoFromClient(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("id") int id) {

        User user = new User();
        user.setId(id);

        response.setContentType("application/json");
        PrintWriter out = null;
        JSONObject json = new JSONObject();

        try {   
            out = response.getWriter();

            user = testService.queryByID(user);
            if (user != null) {
                json.put("status", 1);
                json.put("user", user);
                out.write(json.toString());
            } else {        
                json.put("status", 0);
                json.put("user", null);
                out.write(json.toString());
            }
        } catch (Exception e) {
            e.toString();
            json.put("status", -1);
            json.put("user", null);
            out.write(json.toString());
        } finally{
            out.flush();
            out.close();
        }
    }   
    //--------------------查询单个用户信息 End-----------------------



    //--------------------删除某个用户信息 Start-----------------------
    //访问delete页面
    @RequestMapping("/deletePage.do")
    public String deletePage(){
        return "delete";
    }
    //处理来自浏览器的删除请求,具体逻辑在前台页面的js函数中实现
    @RequestMapping("/delete.do")
    public void deleteFromJspPage(@RequestParam("id") int id,HttpServletRequest request,HttpServletResponse response, Model model){

        String result = "{\"result\":\"error\"}";

        try {   
            if(testService.deleteByID(id)){
                result = "{\"result\":\"success\"}";
                System.out.println( "删除成功!\n");
            }else{
                result = "{\"result\":\"failure\"}";
                System.out.println( "删除失败!\n");
            }

            response.setContentType("application/json");
            PrintWriter out = response.getWriter();
            out.write(result);

        } catch (Exception e) {
            e.printStackTrace();
            result = "{\"result\":\"failure\"}";
            System.out.println( "删除失败!\n");
        } 
    }   
    //处理来自客户端的删除请求,并返回json格式的删除结果(1:成功;0:失败;-1:异常)
    @RequestMapping("/delete.json")
    public void deleteFromClient(@RequestParam("id") int id,HttpServletRequest request,HttpServletResponse response, Model model){

        response.setContentType("application/json");
        PrintWriter out = null;
        JSONObject json = new JSONObject();

        try {   
            out = response.getWriter();

            if(testService.deleteByID(id)){
                json.put("status", 1);
                out.write(json.toString());
            }else{
                json.put("status", 0);
                out.write(json.toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
            json.put("status", -1);
            out.write(json.toString());
        } finally{
            out.flush();
            out.close();
        }
    }
    //--------------------删除某个用户信息 End-----------------------


    //--------------------获取所有用户信息 Start-----------------------
    //处理来自浏览器的请求,切换页面到所有用户信息列表
    @RequestMapping("/userlistPage.do")
    public String getAllUserFromJspPage(HttpServletRequest request, Model model){
        try{
            List<User> userList = testService.queryAllUser();       
            model.addAttribute("userList", userList);
        }catch (Exception e){
            e.toString();
            model.addAttribute("userList", null);
        }

        return "showAllUser";
    }
    //处理来自客户端的请求,并将json格式的结果返回。
    @RequestMapping("/userListPage.json")
    public void getAllUserFromClient(HttpServletResponse response){

        response.setContentType("application/json");
        PrintWriter out = null;
        JSONObject json = new JSONObject();

        try {   
            out = response.getWriter();
            List<User> userList = testService.queryAllUser();

            if(userList !=null){
                json.put("status", 1);
                json.put("userList", userList);
                out.write(json.toString());
            }else{
                json.put("status", 0);
                json.put("userList", null);
                out.write(json.toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
            json.put("status", -1);
            json.put("userList", null);
            out.write(json.toString());
        } finally{
            out.flush();
            out.close();
        }   
    }
    //--------------------获取所有用户信息 End-----------------------
}

解析:
- 1.每个函数的作用,具体已经在注释中阐明。这里没有update函数。
- 2.处理来自浏览器jsp前台页面的“删除”请求的deleteFromJspPage()函数有所不同,原因是:jsp前台页面上进行删除某条记录的操作时,删除成功或者失败时,需要给用户一个反馈(例如,“删除成功”“删除失败”),因此,在相关delete操作页面,加了一个js函数,这个js函数需要的也是String类型的json格式结果,因此,才如上编写delete函数。

4.经验总结

在此次案例实践过程中,我犯了几个错误,大大了影响了项目速度,所以,这里总结一下:

-1. android客户端连接服务器时,总是报错:http://192.168.0.108:8088/ refused connection。
原因:第一,android项目的怕配置文件AndroiManifest.xml中,忘记了添加网络访问权限:

<uses-permission android:name="android.permission.INTERNET" />

-2. android客户端:serverconfiguration.java,配置服务器访问地址时,地址选择错误:127.0.0.1,localhost,还是本机所在wifi环境下的192.168.0.108,亦或者是公网IP地址?
分析:因为我使用的是真机测试,因此,需要将手机和服务器置于一个网络内。意思就是,或者手机和服务器PC都连接同一个WiFi(这样两者就在一个局域网内了);或者手机和服务器PC都直接连接公网(服务器PC的IP地址或者是公网IP,或者是路由器环境下进行映射操作,指向该服务器);亦或者,将服务器PC通过USB连接手机,通过手机USB上Internet,这样手机和PC也在一个网络内了(手机和PC都会分配一个域内地址:192.168.***.***)。
由于,我将服务器PC连接了路由器wifi,而手机却使用的移动数据,所以,android客户端一直连接不上。

-3. 服务器端项目testSSM和客户端项目testSSMServer,都必须添加json数据传递所必需的jar包,这样json数据才可以在服务器和android客户端之间进行传递和解析。
android:testSSMServer
这里写图片描述

server:testSSM

这里写图片描述

希望大家能一次性搭建好环境~

项目源代码下载

展开阅读全文

没有更多推荐了,返回首页