Spring MVC框架一个实例的手动实现
文件结构:
SpringMVC05 // 应用程序名
----index.html // 欢迎文件,主目录下的文件可以被URL直接访问到
----WEB-INF // 这个目录下的文件将被保护起来不能直接被URL访问
--------web.xml // 应用的配置文件
--------classes // 放置Java类文件
--------config // 这是指定的SpringMVC配置文件的路径
--------jsp // 放置不想被URL直接访问的静态文件
--------lib // 引用的库文件欢迎文件:
配置将在Web.xml文件中进行,我配置为 地址/SpringMVC05 将会访问到欢迎文件
<li><a href="list_book">show all books</a></li>
<li><a href="input_insert_book">insert a book</a></li>如果超链接没有在最前面加上’/’那么将会扩展到当前URL的后面形成新的URL
如果加上了’/’将会在应用程序的根路径下扩展URL
Web.xml文件:
在SpringMVC框架下,不需要配置自己的servlet,只需要配置一个框架下已有的DispatcherServlet,他将完成许多工作,比如解析URL等,不需要再自己实现
配置DispatcherServlet的时候会需要一个配置文件
<servlet-class>是固定的,<servlet-name>自己定义,<url-pattern>表示在怎样的URL下使用DispatcherServlet,一般是表示所有URL的“/”
<servlet>
        <servlet-name>springdemo</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
        <servlet-name>springdemo</servlet-name>
        <url-pattern>/</url-pattern>
</servlet-mapping>DispatcherServlet在初始化的时候会去WEB-INF下找对应的 servletname-servlet.xml,这个servletname是自己定义的。
如果不想使用默认的配置文件,那么可以在<init-param>中配置值当的文件名和文件路径,如:
<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>路径/xxx.xml</param-value>
</init-param>还要再此文件中配置欢迎文件等
Config文件夹:
放置指定的配置文件,DispatcherServlet的配置文件用于配置这个servlet的行为属性等
比如去哪个包扫描由注解指定的控制器,哪个包扫描由注解指定的用于依赖注入的Service,配置视图解析器-去掉共有的前后缀
下面这个元素的配置也是必要的,缺少元素可能会导致错误
<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:mvc="http://www.springframework.org/schema/mvc"
	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/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">下面的元素是配置Spring框架的扫描包,当框架想要找控制器或用于依赖注入的类的时候会到这里配置的包下找
<context:component-scan base-package="SpringMVC.service"/>
<context:component-scan base-package="SpringMVC.controller" />因为DispatcherServlet配置的是拦截所有URL,但是指向静态页面的URL是不需要DispatcherServlet处理的,所以要在这里配置怎样的URL不会被DispatcherServlet拦截:这里配置的是后缀为.html的URL将不会被拦截
<mvc:annotation-driven />
<mvc:resources location="/" mapping="/*.html" />配置视图解析器:为避免每次调用视图的时候都需要完整的路径,所以在视图解析器中配置共有的前缀后缀
<bean id="viewResolver"
	class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/jsp/" />
	<property name="suffix" value=".jsp" />
</bean>Lib库文件:
在使用多个库文件的时候,如果有jar包冲突的话,会在运行的时候产生500服务错误。手动的弊端,所以最好使用同一版本的jar文件
Classes文件夹:
文件结构:
Classes
---- SpringMVC
--------controller
------------BookController.java
--------service
------------BookService.java
------------BookServiceImpl.java
--------model
------------Book.java含有三个包:SpringMVC.controller,SpringMVC.service,SpringMVC.model
控制器:
使用基于注解的控制器:@Controller来源于org.springframework.stereotype.Controller,标识一个类为控制器类。Spring框架通过扫描来寻找应用程序中所有基于注解的控制器类
在Spring配置文件中应用<component-scan/>元素来配置Spring去哪里扫描控制器
<context:component-scan base-package=”basePackage”>通过注解@RequestMapping指定一个方法映射到的URI和方法。
- 可以用于标识一个控制器类的URL,表示类中的方法共有的URL前缀。如果只有一个参数,那么默认为value。
- @RequestMapping(value = “URL” method = {RequestMethod.XX})
- 修饰的方法成为请求处理方法
返回值:ModelAndView/Void/String等。String会被Spring框架解析为视图的路径。但是在String前面加上”forward:”或”redirect:”是生成一个重定向或转发的URL
参数:如果有Model参数,那么Spring MVC会在请求处理方法被调用的时候创建Model对象,用于添加在视图中要显示的属性
@RequestBody用于修饰已经被@RequestMappin修饰的方法。通常由@RequestMapping修饰的方法返回值会被解析为跳转路径,比如String、ModelAndView等,当该方法再次被@ RequestBody修饰之后,返回值将直接写入到HTTP的响应正文中。通常用于异步请求
请求参数:传统Servlet将通过HttpServletRequest.getParameter方法获取参数。Spring MVC允许直接将参数传递到方法中。在方法的参数列表中用@RequestParam标识这是一个从URL中获取的参数
路径变量:在@RequestMapping配置的URL模式的后面续加用花括号包含的参数名,这样就可以在请求URL中用“/”之间的字符串为参数赋值。Spring为尽力将路径变量转化为一个非字符串类型
PathVariable如果不写全参数会认为是debug级别的,会在运行的时候去掉,导致找不到变量Name for argument type [long] not available, and parameter name information not found in class file either.
@RequestMapping(value = "/delete_book/{id}", method = {RequestMethod.POST,RequestMethod.GET})
public String deleteBook(Model model,@PathVariable(value="id") int id){...}依赖注入:
在控制器中需要调用数据库的服务,数据库的服务封装在Service包中,所以需要一个service类,这里通过依赖注入实现
Service包中实现了一个BookService接口,定义了会用到的基本方法。还有一个实现该接口的类BookServiceImpl
在控制器中将会使用这个接口作为对象名,而使用BookServiceImpl作为实际对象,这样在改变接口的具体实现方式的时候不需要修改控制器,降低耦合
将BookServiceImpl类用@Service注解,这样Spring框架就会直到这个类可以用于依赖注入,框架会在需要的地方通过调用这个类的无参构造函数生成对象进行注入。这里无参构造函数是必要的,否则将无法注入
在控制器中只需要声明一个引用,并将这个引用通过@Autowired注解,那么框架就会知道这里需要生成一个合适的对象赋给这个引用。而这里只需要创建一个接口类型的引用
请求处理方法:
listBook:该控制器向服务类请求数据库中所有数据,将返回的数据放到Model中发送到lit_book页面
@RequestMapping(value = "/list_book", method = {RequestMethod.POST,RequestMethod.GET})
public String listBook(Model model)
{
    ArrayList<Book> bookList = bookService.get();// 向服务器类请求数据
    model.addAttribute("bookList",bookList);// 请求到的数据发送到页面
    return "list_book";// 调用页面
}
inputInsertBook:当点击页面上的新增数据按钮时会生成URL:”SpringMVC05/input_insert_book”,即跳转到这个请求处理方法,这个方法创建一个对象传到页面用于接收页面的表单数据,返回” input_insert_book”解析为input_insert_book.jsp页面
@RequestMapping(value = "/input_insert_book", method = {RequestMethod.POST,RequestMethod.GET})
public String inputInsertBook(Model model)
{
    model.addAttribute("book",new Book());
    return "input_insert_book";
}
insertBook:在提交插入表单的时候会生成URL:”SpringMVC05/input_insert_book”,即跳转到这个请求处理方法,方法中声明参数@ModelAttribute Book book用于接收页面生成的表单数据,向Model中写入插入数据库中成功或失败的信息,转发到控制器listBook,此时listBook的Model中将含有成功或失败的信息
当字符串加上forward或redirect修饰的时候,框架将不会把这个字符串解析为视图,而是重新生成一个URL。此时这个URL将会被分配到listBook
@RequestMapping(value = "/insert_book", method = {RequestMethod.POST,RequestMethod.GET})
public String insertBook(Model model,@ModelAttribute Book book)
{
    // ...
    return "forward:/list_book";// 转发到新的URL
}
可以看出URL是插入的URL而不是展示的,这正是转发的效果
deleteBook:当在list_book页面上点击删除按钮时,页面会在生成的URL后面加上参数id,值为对应的条目的id号,请求处理方法将根据这个值删除数据库中的数据,方法的参数列表需要声明对应的路径变量@PathVariable(value="id") int id。向Model中写入插入数据库中成功或失败的信息,转发到控制器listBook,此时listBook的Model中将含有成功或失败的信息
inputUpdateBook:当在list_book页面上点击编辑按钮时,页面会在生成的URL后面加上参数id,值为对应的条目的id号,方法的参数列表需要声明对应的路径变量@PathVariable(value="id") int id,方法会根据这个id向数据库请求旧数据并发送到页面,方法也会将id发送到页面,因为随后页面需要将id发送到更新的请求处理方法用于更新指定项。向Model中写入一个承接页面表单输入数据的book对象。跳转到input_update_book页面
@RequestMapping(value = "/input_update_book/{id}", method = {RequestMethod.POST,RequestMethod.GET})
public String inputUpdateBook(Model model,@PathVariable(value="id") int id)
{
    model.addAttribute("oldBook",bookService.get(id));
    model.addAttribute("id",id);
    model.addAttribute("book",new Book());
    return ("input_update_book");
}
updateBook:页面将id放到路径变量中,将新数据对应的对象放到方法参数的@ModelAttribute Book book中。方法向数据库更新数据。转发到litBook方法
注:我在请求处理方法中重新生成URL调用了其他的请求控制方法,这样做是不好的,层间的调用会使代码结构混乱。更好的方式是重新调用服务层获取数据,返回视图。而不是转发到另一个请求处理方法。
Model文件夹:
有一个Book类和Category类,Book类的一个数据成员是Category类,需要实现无参构造函数,框架将会使用到,否则可能会无法生成对象而产生错误
需要为数据实现get和set访问器
Service文件夹:
BookService接口和实现BookService接口的BookServiceImpl类
接口中声明将会使用到的方法签名
BookServiceImpl中实现这些方法:首先在无参构造函数中调用初始化函数,用于形成对数据库的连接。在实现的接口类中将会通过初始化生成的数据库连接进行数据库操作。这个类需要用@Service进行注解,用于依赖注入
// constructor
public BookServiceImpl()
{
    init();
}
// initial function
// connect database
private void init()
{
    // database
    try
    {
        Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
        String url = "jdbc:oracle:thin:@localhost:xxxx:xxxx";// localhost是本机地址,可更改为IP地址
        String user = "biaoJM";
        String password = "xxxxxx";
        connectionOfOracle = DriverManager.getConnection(url, user, password);// 获取连接
        statementOfOracle = connectionOfOracle.createStatement();
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}
Jsp文件夹:
会有三个视图,对应三个文件
对于要使用特殊功能的需要在开头加上对应的项:
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>List_book:用于显示从数据库中所有的数据以及必要的信息,比如当删除一条数据后将会自动跳转到这个界面并显示删除成功的信息。并且每一条数据后面都对应有修改和删除按钮。最下面会有插入数据的按钮。因为传到视图的数据是一个数组,所以循环展示
<c:forEach items="${bookList}" var="book">
<tr>
    <td>${book.id}</td>
    <td>${book.category.name}</td>
    <td>${book.name}</td>
    <td>${book.author}</td>
    <td>${book.price}</td>
    <td><a href="/SpringMVC05/input_update_book/${book.id}">edit</a></td>
    <td><a href="/SpringMVC05/delete_book/${book.id}">delete</a></td>
</tr>
</c:forEach>
input_insert_book:是用户想要插入一条数据的时候看到的界面,用户会在相应的输入框输入数据,有提交按钮,点击后会调用另外的方法插入数据
<form:form commandName="book" action="/SpringMVC05/insert_book" method="POST"><tr>
    <td>category id:</td>
    <td><form:input id="categoryid" path="category.id"/></td>
</tr>
input_update_book:是用户想要更新一条数据的时候看到的界面,输入框会默认显示当前要修改的项的旧数据,用户修改后提交,将会调用相应的更新方法进行更新。value表示设置默认值
<tr>
    <td>category id:</td>
    <td><form:input id="categoryid" path="category.id" value="${oldBook.category.id}"/></td>
</tr>
页面和控制器的数据传输:
方法->页面:
请求处理方法将含有Model参数,框架在调用方法的时候会创建这个对象,用于向这个方法转到的地方发送数据。通过model的model.addAttribute(“identifier”,Object o)方法向这个对象中添加数据,如果这个方法返回到的URL是一个页面,那么在页面中就可以通过${identifier}来访问,也可以通过”.”来访问类的属性,这时框架是通过get/set访问器进行的。如果这个方法通过重定向或转发返回到的URL定向到了另一个请求处理方法,那么重定向的数据将会丢失,转发的数据将会整合到新的请求处理方法的Model中
页面->方法:
通过表单标签的数据绑定功能实现,
在页面文件头加上%@taglib uri="http://www.springframework.org/tags/form" prefix="yourPrefix"%来声明这个文件将使用Spring的表单标签进行数据绑定,并且是通过在标签的前面加上”yourPrefix:”前缀实现声明的,在form标签中的commandName属性来指定这个表单绑定到哪个对象中,在form的input子选项中通过path属性指定这个项绑定到对象的哪个属性,如果属性也是一个对象,可以通过”.”运算符指定到内部的属性。这个对象将提交到form的action指定的URL中。在调用这个页面的方法中需要向这个页面发送一个对象作为容器,form的数据将绑定到这个对象中,并提交这个对象。接收的方法将需要在参数列表中添加 @ ModelAttribute注解的对象,用于接收对象。这三个部分指定的对象名需要保持一致
编译:
javac -cp ..\lib\spring-beans-4.0.0.RELEASE.jar;..\lib\spring-context-4.0.0.RELEASE.jar;..\lib\spring-web-4.0.0.RELEASE.jar;..\lib\spring-core-4.0.0.RELEASE.jar;..\lib\spring-expression-4.0.0.RELEASE.jar;..\lib\standard.jar;..\lib\spring-aop-4.0.0.RELEASE.jar;..\lib\spring-webmvc-4.0.0.RELEASE.jar;..\lib\jstl.jar;..\lib\commons-logging-1.1.2.jar;D:\work\java\web\apache-tomcat-7.0.90\lib\servlet-api.jar;. SpringMVC\controller\BookController.java问题:
当Spring的版本和JDK的版本有冲突的时候,也会是500,此时会在Tomcat的界面上显示异常。
Spring3.x和JDK8有兼容问题,所以要使用更高的Spring版本
源码:
https://github.com/biaoJM/SpringMVC05
Spring MVC框架一个实例的手动实现的更多相关文章
- Spring MVC框架实例
		Spring MVC 背景介绍 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,能够选择是使用内置的 Spring Web 框架还是 ... 
- Spring MVC框架下的第一个Hello World程序
		本程序是一个maven程序,使用maven方便管理jar包和程序,简化了操作步骤.本程序的目的是通过一个简单的程序,了解Spring MVC框架的基本工作流程,由简入繁的学习Spring MVC框架, ... 
- 从零开始学 Java - 搭建 Spring MVC 框架
		没有什么比一个时代的没落更令人伤感的了 整个社会和人都在追求创新.进步.成长,没有人愿意停步不前,一个个老事物慢慢从我们生活中消失掉真的令人那么伤感么?或者说被取代?我想有些是的,但有些东西其实并不是 ... 
- 【WEB】初探Spring MVC框架
		Spring MVC框架算是当下比较流行的Java开源框架.但实话实说,做了几年WEB项目,完全没有SpringMVC实战经验,乃至在某些交流场合下被同行严重鄙视“奥特曼”了.“心塞”的同时,只好默默 ... 
- Spring mvc框架 controller间跳转 ,重定向 ,传参
		一.需求背景 1. 需求:spring MVC框架controller间跳转,需重定向.有几种情况:不带参数跳转,带参数拼接url形式跳转,带参数不拼接参数跳转,页面也能显示. @Req ... 
- spring mvc 框架搭建及详解
		现 在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不 ... 
- spring MVC框架入门(外加SSM整合)
		spring MVC框架 一.什么是sping MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 W ... 
- 十七、IntelliJ IDEA 中的 Maven 项目初体验及搭建 Spring MVC 框架
		我们已经将 IntelliJ IDEA 中的 Maven 项目的框架搭建完成.接着上文,在本文中,我们更近一步,利用 Tomcat 运行我们的 Web 项目. 如上图所示,我们进一步扩展了项目的结构, ... 
- Spring MVC 框架搭建及具体解释
		如今主流的Web MVC框架除了Struts这个主力 外.其次就是Spring MVC了,因此这也是作为一名程序猿需要掌握的主流框架.框架选择多了.应对多变的需求和业务时,可实行的方案自然就多了. 只 ... 
随机推荐
- weboffice7
			document.all.WebOffice1.ShowToolBar = false; 
- C#的常见算法(面试)(转)
			一.求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m //方法一,通过顺序规律写程序,同时也知道flag标志位的重要性. static int F1(int m) { ; ... 
- 【原创】JMS发布者订阅者【异步接收消息】
			发布订阅模式和PTP方式不同之处为后者依赖于一个Topic话题: package com.thunisoft.jms.mine.topic; import java.util.HashMap; imp ... 
- Msql免安装版安装
			文首提要: 我下载的MySQL版本是:mysql-5.7.17-winx64.zip Archive版:系统:Windows7 64位. 一.解压文件 下载好MySQL后, ... 
- Java使用HttpURLConnection上传文件(转)
			从普通Web页面上传文件很简单,只需要在form标签叫上enctype="multipart/form-data"即可,剩余工作便都交给浏览器去完成数据收集并发送Http请求.但是 ... 
- DCDCBigBig's first blog @cnblogs~
			其实初二末的时候我就在CSDN上开了博客(主要是为了存模板),但是无奈CSDN的页面真的太辣眼睛了…… 然后我就加入博客园欢快的大家庭啦!!!顺便膜拜巨佬学长%%%(我是蒟蒻不要喷我) 页面设置感谢x ... 
- luogu  P1622 释放囚犯
			题目描述 Caima王国中有一个奇怪的监狱,这个监狱一共有P个牢房,这些牢房一字排开,第i个紧挨着第i+1个(最后一个除外).现在正好牢房是满的. 上级下发了一个释放名单,要求每天释放名单上的一个人. ... 
- javaweb集成swagger
			一.添加依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-sw ... 
- visio使用技巧
			1.背景放大: 按住Ctrl键,滚动鼠标滚轮,即可调整背景大小,这是改变的显示比例 2.背景: 按住Ctrl+E,在背景边框处拖动图标,即可拉大或者缩小背景,这是实际更改背景大小. 
- mysql日期加减运算
			MySQL 日期类型MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间 日期格式 日期范围 --------- ... 
