JavaWeb Spring 框架学习使用

后端2015-05-200 篇评论 Java Spring

在 PHP 较为熟练地掌握之后,我开始了 JavaWeb 的学习,到现在已经开始使用 Spring 框架进行项目开发了。大多数人的 JavaWeb 都是从 JSP 学起的,这对于了解 HTML 的人来说入门较为方便,能由浅入深地进入 JavaWeb。而我认为这样的学习不是最好的方式,应该从 JSP 的底层——Servlet 学起。

事实上,所有的 JSP 页面在部署运行时,都是先被 JSP 容器翻译成 Servlet 这类 Java 文件,然后再由 JDK 编译成 class 二进制文件运行的。由此而言,首先掌握 JSP 的实质才是更重要的。这里我就不对 JSP 和 Servlet 做过多介绍,说说 Spring 这个 JavaWeb 框架。

JavaWeb 有三个知名的框架,分别是 Spring、Struts、Hibernate,缩写为 SSH。目前我只学会了使用 Spring 进行项目开发,对后两者知之甚少,就不在此说明了,等下次学习的时候再写文章介绍。

我对 Spring 的理解

对于 Spring,我现在所了解的:

  1. Spring 是个 MVC 架构的框架,M、V、C 分别为 Model(模型)、View(视图)、Controller(控制器),由 Controller 对接口进行控制、转发业务处理请求,Model 负责输出所处理的数据,View 负责显示 JSP 等页面,让数据展示在其上。
  2. Spring 的特色在于自动 Setter 注入与自动 JavaBean 装配,不需要手动 set 或者在 web.xml 中写配置项,可以减少开发人员不必要的麻烦和重复劳动。
  3. Spring 的数据库连接池能够避免每一次执行时连接数据库,程序结束时关闭连接这种低效率的方式。这种连接池始终保持着对数据库的连接,在每次连接结束时把连接放回连接池中,下次需要连接数据库时从连接池中取出,减少不必要的连接数据库时间损耗。

Spring 项目基本结构

在 Spring 框架下的项目开发,通常都是模块化的,一个具体的功能模块对应一个 JAVA 包,这个 JAVA 包下通常会有这四种类文件:XXXController、XXXService、XXXDAO、XXXBean,下面一一说明。

一个包里的文件结构:

spring_dir379.png

Controller 层

Spring 的 Controller 是个强大的东东,负责处理 Response 请求,复杂的业务逻辑传递给 Service,最后完成处理返回 Response 相应,简单说来就是处理交互。Spring 的所有 Controller 收到的参数共由一个 Servlet 转发,所以 Controller 可以如同原生 Servlet 那样处理 HTTPServlet 请求和响应。给 Controller 或者 Controller 中的方法绑定 URL 不需要写 web.xml 文件,只需要在需要绑定的方法上方加上 @requestMapping("相对项目根目录的 url 地址") 注解,在重启 Tomcat 服务器后可通过直接访问此 URL 来调用绑定的方法,显然简单简洁。Controller 通常返回 ModelAndView(即视图和模型)作为响应的页面,或者在同样标注 @responseBody 的情况下返回 Map 类型的 Model 数据以 JSON 格式作为响应,可以大大减少需要的代码,极大的避免冗余。

Controller 层代码示例:

package com.example.user;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * Controller 控制层
 * @author: Dremy
 */
@Controller
public class UserController {

    /**
     * Spring 自动装配,不需要在调用前进行初始化
     */
    @Autowired
    private UserService service;


    /**
     * 返回 Model 和 View 示例
     * @param: id
     * @return: view, model
     */
    @RequestMapping("/page1")
    public ModelAndView getModelAndView(String id) {
        Map<String, Object> model = new HashMap<>();    // 新建一个 Map 对象作为 Model
        UserBean bean = service.getUserById(id);     // 调用 Service 层进行数据处理
        model.put("obj", bean);      // 将数据处理结果存入 Model 中
        return new ModelAndView("page1.jsp", model); // 返回 View 和 Model
    }


    /**
     * 返回 JSON 格式的 Model 示例,常作为接口调用
     * @param: id
     * @return: model
     */
    @RequestMapping("/inter1")
    @ResponseBody
    public Map<String, Object> getModel(String id) {
        Map<String, Object> model = new HashMap<>();    // 新建一个 Map 对象作为 Model
        UserBean bean = service.getUserById(id);     // 调用 Service 层进行数据处理
        model.put("obj", bean);           // 将数据处理结果存入 Model 中
        return model; // 返回将 Model 以 JSON 格式返回
    }
}

Service 层

Service 这层负责处理业务逻辑,交互之外的业务逻辑大多由它来实现,主要是对 Controller 传入的参数进行处理,根据需要调用 DAO 层获取数据。对于一个模块的核心功能实现,都是在这层进行封装,并可供其它模块调用,可维护性较高。

Service 层代码示例:

package com.example.user;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.common.Util.SysUtil;


/**
 * Service 业务层
 * @author: Dremy
 */
@Service
public class UserService {

    @Autowired
    private UserDAO dao;

    /**
     * 通过调用 dao 层方法得到 Map 数据,通过 Bean 中
     * 自身的方法转换为 JavaBean
     * @param: id
     * @return: bean
     */
    public UserBean getUserById(String id) {
        UserBean bean = new UserBean();
        Map<String, Object> dataMap = dao.getUserById(id);
        return bean.changeMap2Bean(dataMap);
    }
}

DAO 层

DAO(Data Access Object 数据访问对象)层是数据的主要来源,通过 SQL 语句连接数据库进行查询,返回结果,供 Service 层进行处理。由于 Spring 对 JDBC 的封装较为完善,且拥有数据库连接池,因此对数据库的查询操作变得异常简单。若在 DAO 与 JDBC 之间再封装一些结构化的方法,则可以直接返回给 Service 层 Map 或是 MapList 类型的数据,这样 DAO 层的每个方法都简单明了,通常一条 SQL 语句、一条预处理绑定语句、一条返回语句就足矣。

DAO 层代码示例:

package com.example.user;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.example.common.db.DBCommon;

/**
 * DAO 数据层
 * @author: Dremy
 */
@Repository
public class UserDAO {

    @Autowired
    private DBCommon db;

    /**
     * 通过 Id 获取 users 表中的某条记录信息
     * @param: id
     * @return: Map
     */
    public Map<String, Object> getUserById(String id) {

        String sql = "SELECT * From users WHERE id = ?";
        Object[] param = new Object[] {id};
        return db.queryForMap(sql, param);
    }
}

DAO 层中我是通过调用经过封装的 DB 层来获取数据库中的数据的,这样的好处就是可以根据需要返回 Map 或是 List 或是 MapList 类型的数据,随心所欲。当然 Spring 的 JDBC 已经封装了这一步,也就不需要额外的代码了。

Bean

Bean(JavaBean)层是对数据对象的封装,本质上不属于 Spring 中的一个层次,通常提供一个模块所用到的数据结构的所有成员体,方便这个模块数据的传递。JavaBean 本质上是一个 Map 对象,内含 Key 为成员名的又一层 Map 对象,并可以直接传给 Controller 作为 Model 返回给 JSP 页面或是作为 JSON 格式输出。

Bean 中代码示例:

package com.example.user;

import java.util.Map;

import com.example.common.Util.SysUtil;
/**
 * JavaBean 层
 * @author: Dremy
 */
public class UserBean {

    private String id;          // 用户 ID

    private String username;     // 用户名

    private String userType;    // 用户类型

    private String schoolNumber;// 学生学号

    /**
     * 将 Map 类型的数据经过转换后存入 bean 中
     * 注:SysUtil 是已经过封装的一个工具类,
     *     其中的 Object2String 将对象转化为字符串
     * @param: dataMap
     * @return: userBean
     */
    public UserBean changeMap2Bean(Map<String, Object> dataMap) {
        if (SysUtil.isEmptyMap(dataMap)) {
            return null;
        }
        UserBean bean = new UserBean();
        bean.setId(SysUtil.object2Str(dataMap.get("id")));
        bean.setUsername(SysUtil.object2Str(dataMap.get("username")));
        bean.setUserType(SysUtil.object2Str(dataMap.get("user_type")));
        bean.setSchoolNumber(SysUtil.object2Str(dataMap.get("school_number")));
        return bean;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserType() {
        return userType;
    }

    public void setUserType(String userType) {
        this.userType = userType;
    }

    public String getSchoolNumber() {
        return schoolNumber;
    }

    public void setSchoolNumber(String schoolNumber) {
        this.schoolNumber = schoolNumber;
    }
}

重启 Tomcat 服务器之后,就可以通过访问 Controller 绑定的 URL 来执行程序了

评论区

发表评论
用户名
(必填)
电子邮箱
(必填)
个人网站
(选填)
评论内容
Copyright © 2017 dremy.cn
皖ICP备16015002号