搭建SpringMVC与SpringBoot项目

最近项目组后台经历了从Python服务到SpringCloud微服务系统重构,因此有必要去学习一下Spring,本文主要整理了SpringMVCSpringBoot的Demo项目搭建,用于入门JavaWeb开发。

<!--more-->

本文主要介绍两个框架的Demo项目搭建,不涉及Java语言、相关概念和具体细节。

1. 预备环境

1.1. 了解IOC与DI

Java Web需要掌握的SSM框架:Spring、Spring MVC、MyBaits,需要理解Spring的IOC 反转控制和DI 依赖注入思想,对于前端而言,可以先看看下面的文章

IOC(控制反转)主要目的是解耦各个类的依赖关系,在常规的设计中,我们需要在初始化对象中声明其依赖的对象;在IOC中,这些依赖关系交给容器处理,各个类之间不再需要自己去维护依赖的对象。

容器有两个作用

  • 被依赖的类需要先在容器中进行注册
  • 应用程序需要先声明其依赖,然后等待容器在合适的时机将其依赖进行注入

这样保证了各个类之间是松散耦合,便于测试与功能复用

1.2. 安装Java

安装略。

安装完成后使用java --version查看对应版本。

1.3. 安装tomcat

去官网http://tomcat.apache.org/下载tar.gz安装包,然后解压到目录,记录配置地址即可

1.4. 安装maven

参考

首先去官网下载tar包,解压到~/develop/maven,然后配置下环境变量

export M3_HOME=/usr/local/etc/maven/apache-maven-3.6.3
export PATH=$M3_HOME/bin:$PATH

然后使用mvn -v测试是否安装配置成功

2. SpringMVC

有两种方式创建SpringMVC项目

2.1. 使用IDEA直接创建项目

参考

使用IDEA创建项目时选择SpringMVC项目,然后一直点击Next,最后等待依赖安装完成即可,之后还需要配置Tomcat。

2.2. 使用IDEA + maven初始化项目

参考:IDEA使用maven创建springMVC项目

大概步骤为

首先使用IDEA创建maven项目,可以修改maven镜像加快速度,配置文件位于maven安装目录/conf/setting.xml

<mirror>
    <id>alimaven</id>
    <mirrorOf>central</mirrorOf>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>

然后向pom.xml文件中添加相关配置依赖,添加后maven会自动下载依赖包

<dependency>
    <groupId>xxx</groupId>
    <artifactId>xxx</artifactId>
    <version>4.11</version>
    <scope>xxx</scope>
</dependency>

接着右键项目,点击Add Framework Support,添加SpringMVC项目,IDEA会自动添加dispatcher-servlet.xml等配置文件。操作时发现右键选择时没有SpringMVC选项,这是因为ProjectStructure中已经存在Spring对应Module,需要先移除该Module后重新添加。参考IDEA右键项目中的Add Frameworks Support没有spring

然后就可以进行后面的操作了。

2.3. 控制器与视图

src目录下新建一个package,然后创建一个控制器HelloController

package com.shymean.test;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/")
public class HelloController {
    @RequestMapping("/test") // 当前方法对应的url
    public ModelAndView test() {
        System.out.println("test ..."); // 在控制器执行一些操作
        return "/WEB-INF/jsp/test.jsp"; // 对应的模板文件,下面会介绍如何创建
    }
}

然后在web/WEB-INF/目录下新建一个jsp目录,用于存放模板文件,接着创建一个test.jsp文件,除了顶部的声明,可以看做是一个完整的HTML文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>hello world</h1>
</body>
</html>

这样,我们就实现了访问指定url时,需要执行的控制器方法,然后返回对应的模板内容

2.4. 配置dispatcher-servlet

配置文件位于web/WEB-INF/dispatcher-servlet.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.shymean.test"/>
    <!--指定视图解析器,默认是带*.form后缀的请求-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 视图的路径 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 视图名称后缀  -->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

2.5. 模型

可以返回一个ModelAndView向对应的视图传递数据

package com.shymean.test;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView; // ModelAndView用于向视图绑定传入数据

@Controller
@RequestMapping("/")
public class HelloController {
    @RequestMapping("/test")
    // 返回一个 ModelAndView,该对象上即包含了视图名字,也包含了需要填充的数据
    public ModelAndView test() {
        ModelAndView mv = new ModelAndView();
        mv.addObject("name", "shymean");
        mv.addObject("age", 27);
        mv.setViewName("test");
        return mv;
    }
}

然后在jsp中就可以使用agename这些变量了,

<body>
<h1>hello world</h1>
<p>${age}</p>
<p>${name}</p>
</body>

第一次是从网上复制的一份依赖,使用时发现jsp页面中输出${age}而不是具体的变量名,原因是web.xml声明的jsp版本太低,参考:Spring MVC EL ModelAndView传给JSP的值不显示

3. Spring Boot

参考:

3.1. 环境安装

第一步,IDEA新建项目,选择Spring Initializr,输入GroupArtifact,点Next

第二步,勾选相关启动项

  • Web: Spring Web
  • Template Engines: Thymeleaf
  • SQL: MySQL Driver、JDBC API 和 MyBatis Framework

第三步,点击Finish初始化项目目录,配置Maven、tomcat等,等待IDEA安装相关依赖,第一次安装这里貌似会很耗时~

第四步,Hello World

  • resources/templates目录下新建一个index.html文件
  • java目录下新建一个包com.example.test4.controller,然后创建一个helloController
package com.example.test4.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class helloController {
    @RequestMapping("/index")
    public String index() {
        System.out.println("hello index");
        return "index";
    }
}

第五步,启动项目,浏览器访问http://localhost:8080/index,就可以看见对应index.html文件内容了

3.2. 目录结构

SpringBoot项目分为了四层

  • DAO层,访问数据库,主要定义操作数据库的一些接口,然后通过XML编写SQL语句操作数据库
  • Bean层,也叫model层,模型层,entity层,主要对应数据库查询结果的对象映射
  • Service层,也叫服务层,业务层,主要处理业务逻辑,控制Dao操作数据库并封装查询结果
  • Web层,即Controller层,实现与web前端的交互,主要控制Service处理业务逻辑,然后将结果进行渲染

整个项目目录结构类似于

3.3. Beans

接下来实现一个根据账号密码登录的流程

首先是Bean层,描述数据库查询结果

package com.example.test4.bean;

public class UserBean {
    // 对应数据库相关字段
    private int id;
    private String name;
    private String password;

    // ... 剩下一些get与set接口
}

3.4. Dao

接着是Dao,主要封装数据库的操作

首先配置数据库和mybatis

spring:
  datasource:
    name: shymean  #数据库名
    url: jdbc:mysql://localhost:3306/shymean #url
    username: root  #用户名
    password: 123456  #密码
    driver-class-name: com.mysql.jdbc.Driver  #数据库链接驱动


mybatis:
  mapper-locations: classpath:dao/*.xml  #配置映射文件,会去对应的目录下
  type-aliases-package: com.example.test.bean #配置实体类

然后定义Dao接口

package com.example.test4.dao;

import com.example.test4.bean.UserBean;
import org.springframework.stereotype.Component;

@Component
public interface UserDao {
    // 定义一个根据账号密码查询用户的接口
    UserBean getInfo(String name, String password);
}

定义了接口之后,然后通过mybaits实现

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.test4.dao.UserDao">
    <select id="getInfo" parameterType="String" resultType="com.example.test4.bean.UserBean">
        SELECT * FROM admin_user WHERE name = #{name} AND password = #{password}
    </select>
</mapper>

3.5. Service

首先定义服务接口

package com.example.test4.service;

import com.example.test4.bean.UserBean;

public interface UserService {
    // 暴露一个根据账号和密码登录的接口 
    UserBean loginIn(String name, String password);
}

然后进行实现

package com.example.test4.servceImpl;

import com.example.test4.bean.UserBean;
import com.example.test4.dao.UserDao;
import com.example.test4.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

// 添加Service注解
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao; // 自动注入Dao层实例

    @Override
    public UserBean loginIn(String name, String password) {
        return userDao.getInfo(name, password);
    }
}

3.6. Controller

在Controller中处理网络请求,获取参数并调用Service接口,然后将查询结果返回给用户

package com.example.test4.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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

import com.example.test4.bean.UserBean;
import com.example.test4.service.UserService;

// RestController返回JSON
@RestController
public class apiController {
    //将Service注入Web层
    @Autowired
    UserService userService;

    // 获取请求参数,返回JSON
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public UserBean login(@RequestParam(name = "name") String name, @RequestParam(name = "password") String password) {
        UserBean userBean = userService.loginIn(name, password);
        // todo 生成token啥的...
        return userBean;
    }
}

完成上面的代码实现之后,启动服务,浏览器访问http://localhost:8080/login?name=root&password=root应该就可以看见对应的数据了。

4. 小结

与SpringMVC相比,SpringBoot封装了大量的配置项,使开发人员可以更专注于业务,整体来说,只要知道了SpringBoot项目的基本结构,就能快速上手进行开发。加之当前前后端分离逐渐成为主流,后端无需进行模板渲染相关的工作,用SpringBoot应该会越来越多吧。

经过上面的折腾,现在起码能看懂项目结构和基本代码流程了。在了解了两者的使用和差异之后,就可以进一步去学习SpringCloud了。