springMVC+maven+mybatis+mysql入门
(五)最简单的springMVC后台程序
这一小节,我们会搭建一个最简单的springMVC后台服务程序,初步了解这个框架的开发流程
我们需要使用 (四)创建的Maven Web 工程 中创建的那个工程源码。
1.添加依赖包
我们是基于maven来管理项目的,所以添加依赖包只需要修改pom.xml
文件即可。
从Maven仓库查找包获取依赖配置,在 (二)创建maven工程 中有详细介绍,这里不再赘述。
添加完依赖包的pom.xml
文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springdemo</groupId>
<artifactId>springstart</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>springstart Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.3.13.RELEASE</spring.version>
<jackson.version>2.9.5</jackson.version>
<security.verison>4.1.3.RELEASE</security.verison>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<!-- spring start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${security.verison}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${security.verison}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${security.verison}</version>
</dependency>
<!-- spring end -->
<!-- mysql start -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- mysql end -->
<!-- bonecp start -->
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp-spring</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
<!-- bonecp end -->
<!-- mybatis start -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- mybatis end -->
<!-- redis start-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.8.RELEASE</version>
</dependency>
<!-- redis end -->
</dependencies>
<build>
<finalName>springstart</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
修改完成之后,保存pom.xml
文件,然后就会有个过程,如果本地没有需要的包,maven会从中央仓库拉取这个包,这个跟网速有关,需要一定时间。
如果要问,如何得知需要添加这些依赖包呢?其实就是边用边发现缺了,再查找添加上,慢慢的,配置就完善了。
2.配置web.xml
在src/main/webapp/WEB-INF
下面有一个web.xml
文件,这个是springMVC框架的webapp的主要配置文件
在上一节中我们已经讲过了如何把app放到tomcat下运行,这里我们不再讲,有不清楚的可以看看上一节(四)创建的Maven Web 工程
首先,springMVC的一个核心配置
<servlet>
<servlet-name>springStart</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
其中的 <servlet-name>springStart</servlet-name>
这个是设置servlet的名字,这个随便设定,后面会用到
然后
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
这一段,是springMVC的运行核心
我们先说一下,什么是 servlet,简单的说,servlet就是对用户请求和返回数据的一个调度器。
Tomcat是一个servlet容器,将用户的请求转给servlet处理,将servlet返回的数据返给用户。
而DispatcherServlet就是springMVC实现的一个servlet,工作流程大致如下:
最简单的一个流程说明:用户发出的请求,通过
DispatcherServlet
过滤,根据请求分发到不同的控制器,控制器将不同的请求分发到不同的业务逻辑来处理,最后将数据逐层返回给用户。后面我会单独写文章来讲一讲Servlet,有兴趣的同学可以关注我。
上面这个流程,后面我们可以逐渐实现、体会。
Servlet配置之后,还需要配置一个
<servlet-mapping>
<servlet-name>springStart</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
url-pattern
表示匹配的url规则,具体规则先不细讲,我们这里使用/
表示匹配所有url请求,所有到springStart的请求都要使用DispatcherServlet
处理。
这样,我们修改后的web.xml
文件如下:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<servlet>
<servlet-name>springStart</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springStart</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
把工程加载到tomcat,然后启动tomcat,从Console打印窗口,可以看到运行情况
可以看到,有错误发生,最主要的一句就是
java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/springStart-servlet.xml]
找不到/WEB-INF/springStart-servlet.xml
这个文件,这个也是springMVC的一个主要配置文件
可以看出,默认是在/WEB-INF
目录下找这个文件,文件名的格式就是servlet_name-servlet.xml
那么我们就在这个目录下建一个这个文件,这个文件有一些固定的格式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
</beans>
再运行tomcat看看,没有报错,我们在浏览器输入 http://localhost:8080/springstart/ 可以访问到我们的index.jsp,说明服务正常跑起来了。
前面我们说了,DispatcherServlet
会过滤处理所有的请求,而我们设置的过滤条件是/
,就是所有请求都会被处理,都会发送到控制层,为什么我们这里还没有写所谓的控制层,就已经可以访问页面了呢
我的理解,DispatcherServlet
只会控制对/WEB-INF
下面的页面的访问,对于/webapp下的访问无法控制,在上一小节中我们没有配置servlet,也能访问到index.jsp。
好了,现在我们的基础框架已经搭建起来了,接下来,我们进行各种配置和功能添加
修改servlet配置文件
首先,我们不一定把servlet_name-servlet.xml
放在/WEB-INF/下面,我们更倾向于把所有配置文件放到一个特定目录下,同时,我们也不想就非得叫这个名字,想叫一下其他名字
一般,我们把配置文件放到src/main/resources
下面,我们在这个目录下创建一个文件夹config,后面我们所有的配置文件都放在这里。
复制servlet_name-servlet.xml到config下,改个名字,比如叫mymvc.xml,目录结构如下图
然后,修改web.xml中DispatcherServlet的配置
<servlet>
<servlet-name>springStart</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/mymvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
其中新增的
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/mymvc.xml</param-value>
</init-param>
就是指定servlet的配置文件放在哪里,叫什么名字。
classpath
默认情况下指向的是WEB-INF/classes
这个路径,但是我们的WEB-INF下面没有这个classes啊。。。这个指的编译之后的路径
首先,把servlet_name-servlet.xml
删了,我们试一下新创建的mymvc.xml
有作用没有。
把刚才运行的tomcat停了,重新运行一次,待运行完成后,在浏览器里刷新刚才那个地址http://localhost:8080/springstart/,页面依然显示出来,说明配置有效。
这个时候,我们打开tomcat的安装目录,依次打开webapps\springstart\WEB-INF
,可以看到,WEB-INF
下面有classes
目录,而且classes
下面有config
目录,classpath
指向的就是这个classes
,目前我们没有写java代码,所以这里面还没有class文件,后面会有的。
添加控制器
控制器实际就是对用户访问url的响应控制,简单来说,用户输入 http://localhost:8080/springstart/firstpage 和输入 http://localhost:8080/springstart/secondpage 应该得到不同的响应。
控制器(controller)这部分比较模式化,也就是有固定结构,在MVC框架下,controller本来的定位就是一个简单的接受数据返回数据的功能,具体数据处理,都在业务逻辑层。
首先,在src/main/java下面,创建一个包 com.springstart.controller,然后,在这个包里面,创建一个java类,DemoController.class,具体代码如下:
package com.springstart.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class DemoController {
@RequestMapping(value="/hello",method=RequestMethod.GET)
public String MyFirstController(){
System.out.println("some one call MyFirstController");
return "hello";
}
}
这段代码的意思很简单,就是返回一个字符串hello,只是多了一些注解,我们来解释一下这些注解(关于java的注解请自行百度一下)。
@Controller
这个就是告诉spring,我这个类,是一个controller,实际上,这个就是让这个类成为一个bean,被会spring自动扫描的时候处理为一个bean,但是特定的controller有一些特别的配置,同样的注解还有@Service,@Component等。
@RequestMapping
用来处理请求地址映射,看我们这里写的
@RequestMapping(value="/hello",method=RequestMethod.GET)
这个就是一个最常用的方式,value后面跟的就是地址映射,value="/hello"的意思就是,我们这个方法处理springstart/hello 这个URI,method表示请求的方法,如GET
,POST
,PUT
,DELETE
等,如果不添加method,那么就表示对所有方法进行处理,添加了指定method,就只处理这个类型的请求。
这个注解同时还可以放在类上面,例如:
@Controller
@RequestMapping(value="/user")
public class DemoCon {
@RequestMapping(value="/name",method=RequestMethod.POST)
public String addUserName(){
return null;
}
@RequestMapping(value="/id",method=RequestMethod.POST)
public String addUserId(){
return null;
}
}
这个demo,我们给类DemoCon加了@RequestMapping(value="/user")
注解,表示DemoCon整个类处理 /user的地址请求,下面每个方法的地址请求前需要加上/user
比如方法addUserName处理的就是 /user/name
好了,控制器写好了,我们需要使用它,得增加一些配置。
这个配置要写到mymvc.xml
中,之前,我们这个文件是空的,写点配置进去之后
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.springstart.*"></context:component-scan>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
component-scan
这个的意思就是去扫描base-package
指定位置中的关于bean的注解,比如@Component,@Service,@Controller,@Repository等,而base-package
一般就是包路径
通过component-scan
之后,我们的controller才可以使用
下面的org.springframework.web.servlet.view.InternalResourceViewResolver
这个可以简单的理解为视图处理器,前面我们写的controller返回的是一个字符串 hello,但是,这不是真正的把字符串返回给页面,是告诉servlet返回的是一个叫hello的视图,具体这个视图如何解释呢,就使用这个InternalResourceViewResolver
,下面的参数配置告诉了我们
prefix
是前缀,就是视图的路径
suffix
是后缀,就是视图的后缀
两个结合起来,我们的hello变成了/WEB-INF/pages/hello.jsp
,servlet就把这个页面返给浏览器。
在/WEB-INF/下创建一个pages目录,放一个hello.jsp进去,hello.jsp的源码如下:
<html>
<body>
<h2>This is my HELLO!!</h2>
</body>
</html>
这样,/WEB-INF/ 的目录结构如下:
好了,我们把tomcat运行起来,在浏览器输入 http://localhost:8080/springstart/hello
可以看到 This is my HELLO!! 正确的显示到了页面上。
但是,如果我们像index.jsp一样,自己通过链接http://localhost:8080/springstart/hello.jsp去访问hello.jsp,是无法访问的,提示404错误,这是框架对资源的保护,WEB-INF 下的资源,不能直接访问。
好了,最简单的一个springMVC框架搭建好了,后面我们继续往里面添加各种功能。
本次生成的工程代码在 sprintStart github springStart_basic_1 目录下,请自行下载