SpringMVC(1)

1. 思路理清

src/bean.xml: 是Spring的配置文件(< bean …>),bean管理,一定有该xml文件(可改名,如springmvc.xml)。在生产对象时加载此路径文件。

WebRoot/WEB_INF/web.xml: web应用时才会有该文件,配置servlet等信息。会指向上述的bean.xml。

2. MVC简介

既然MVC是一个设计模式,当然既可以在C/S(客户端服务器)模式下使用,也可以在B/S(浏览器服务器)模式下使用。下面我们介绍在B/S模式下的应用,如下所示:

这里写图片描述

  1. 用户发起Request请求至控制器(Controller),控制器接收用户的请求,并将请求委托给模型进行处理。

  2. 控制器请求模型(Model),模型处理业务数据并得到处理结果,模型通常是指业务逻辑,包括Pojo、Service、Dao等三层

  3. 模型将处理结果返回给控制器

  4. 控制器将模型数据在视图(View)中展示

    说明:web中模型无法将数据直接在视图上显示,需要通过控制器完成。如果在C/S应用中模型是可以将数据在视图中展示的。
    控制器将视图响应结果,Response响应给用户,通过视图展示给用户数据或者处理结果。

  1. Controller的作用

    封装web请求为一个数据对象、调用业务逻辑层来处理数据对象、返回处理数据结果及相应的视图给用户。

  2. Model的作用

    处理业务数据,并返回处理结果

  3. View的作用

    渲染视图,并将数据或处理结果展示给用户

2. 流程

①部署web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <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:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>----③
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

< servlet> 标签指出使用springMVC的Dispatcher Servlet

< init-param> 属性指出springMVC配置文件的路径。文中写法表示src/.xml。如不写该属性,默认和web.xml同目录,即/WEB_INF/

< servlet-mapping> 指出哪些url映射到该servlet。若为 / ,表示所有url。

②配置applicationContext.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" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
    <property name="driverClassName" value="com.mysql.jdbc.Driver">
    </property>
    <property name="url" 
        value="jdbc:mysql:///cloud_note?useUnicode=true&amp;characterEncoding=utf8">
    </property>
</bean>

<bean id="ssf" 
    class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dbcp"></property>
    <property name="mapperLocations" 
        value="classpath:cn/whbing/note/sql/*.xml">
    </property>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="cn.whbing.note.dao">
    </property>
    <!-- 自动注入sqlsessionfactory -->
</bean>

<!-- 开启扫描,扫描Controller,Service组件 -->
<context:component-scan base-package="cn.whbing.note"/> 

<!-- handlermapping,支持@RequestMapping,@ResponseBody,@Exceptionhanlder -->
<mvc:annotation-driven />

</beans>

该配置详解见下文。

3. 代码及原理

①Controller

package cn.whbing.note.controller.notebook;

import javax.annotation.Resource;

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

import cn.whbing.note.entity.NoteResult;
import cn.whbing.note.service.NoteBookService;

@Controller
@RequestMapping("/notebook")
public class addNoteBookController {
    @Resource
    private NoteBookService noteBookService;
    @RequestMapping("/add.do")
    @ResponseBody
    public NoteResult excute(String noteBookName,String userId) {
        NoteResult result=noteBookService.addNoteBook(noteBookName, userId);
        return result;
    }
}

②Service

接口

package cn.whbing.note.service;

import cn.whbing.note.entity.NoteBook;
import cn.whbing.note.entity.NoteResult;

public interface NoteBookService {
    NoteResult loadNoteBooks(String userId);
    NoteResult addNoteBook(String noteBookName,String userId);
}

实现类

package cn.whbing.note.service;

import java.sql.Timestamp;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import cn.whbing.note.dao.NoteBookDao;
import cn.whbing.note.entity.NoteBook;
import cn.whbing.note.entity.NoteResult;
import cn.whbing.note.util.NoteUtil;

@Service
public class NoteBookServiceImp1 implements NoteBookService{

    @Resource
    private NoteBookDao noteBookDao;

    @Override
    public NoteResult loadNoteBooks(String userId) {
        List<NoteBook> list=noteBookDao.findByUser(userId);
        NoteResult result=new NoteResult();
        result.setStatus(0);
        result.setMsg("查询笔记本成功");
        result.setData(list);

        return result;
    }

    @Override
    public NoteResult addNoteBook(String noteBookName,String userId) {
        //用户传入的noteBookName及userId将赋给新建的笔记本
        //新建笔记本
        NoteBook noteBook=new NoteBook();
        noteBook.setCn_notebook_name(noteBookName);
        noteBook.setCn_user_id(userId);
        noteBook.setCn_notebook_type_id("1");//默认类型
        noteBook.setCn_notebook_id(NoteUtil.createId());
        //desc字段先为空
        //创建时间为Timestamp类型
        Timestamp nowTime=new Timestamp(System.currentTimeMillis());
        noteBook.setCn_notebook_createtime(nowTime);
        noteBookDao.save(noteBook);;
        NoteResult result=new NoteResult();
        result.setStatus(0);
        result.setMsg("添加笔记本成功");       
        result.setData(noteBook.getCn_notebook_id());//返回noteId是为了后面工作
        return result;
    }

}

原理解析

1. Dispatcherservlet

DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。

注解

1. SpringMVC的四个基本注解annotation

@Component、@Repository @Service、@Controller

其实,这四个注解的效果都是一样的,(作用)spring都会把它们当做需要注入的Bean加载在上下文中;而@Component (字面意思就是组件),它在你确定不了事哪一个层的时候使用。

但是在项目中,却建议你严格按照除Componen的其余三个注解的含义使用在项目中。这对分层结构的web架构很有好处!!

① 控制层

@Controller // 控制层,就是我们的action层
@RequestMapping(“/notebook”)

public class addNoteBookController {
    @Resource
    private NoteBookService noteBookService;

    @RequestMapping(“/add.do”)
    @ResponseBody

    public NoteResult excute(String noteBookName,String userId) {
        NoteResult result=noteBookService.addNoteBook(noteBookName, userId);
        return result;
    }
}

② 业务逻辑层

@Service(“userService”)
public class UserServiceImpl implements IUserService {
  @Autowired
  @Qualifier(“userDao”)

  private IUserDao userDao;
… …

③ 持久层 ( 即dao层 )

@Repository(“userDao”)
public class UserDaoImpl implements IUserDao {
… …

2. @RequestMapping

RequestMapping是一个用来处理请求地址映射的注解(将请求映射到对应的控制器方法中),可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径

3. @Resource 或@Autowired @Qualifier(“userDao”)

@Resource

@Autowired 
@Qualifier(“userDao”) 

都表示注入对象,前者按名称,后者按类型。

4. @ResponseBody

该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区

返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

实体类entity

笔记本类

package cn.whbing.note.entity;

import java.io.Serializable;
import java.sql.Timestamp;

public class NoteBook implements Serializable{
    private String cn_notebook_id;
    private String cn_user_id;
    private String cn_notebook_type_id;
    private String cn_notebook_name;
    private String cn_notebook_desc;
    private Timestamp cn_notebook_createtime; //java sql下有这个类型
    ... ...

结果类

将操作结果的状态及数据存在结果类中,返回前台的也是这个结果类。通过@responseBody解析成json即可。

package cn.whbing.note.entity;

import java.io.Serializable;

public class NoteResult implements Serializable {
    private int status;  //状态
    private String msg;  //消息
    private Object data=null; //数据

Ajax交互

$.ajax({
        url:"note/add.do",
        type:"post",
        data:{"noteName":noteName,"bookId":bookId,"userId":userId},
        dataType:"json",
        success:function(result){
           if(result.status==0){
              hideAddNoteAlert();//关闭对话框
              var noteId = result.data;//获取笔记ID
              ... ...

说明

1.service层调用dao操作数据库的方法,见后文的mybatis
2.关于Controller中的ModelAndView,是Controller结果的一种返回方式,一般与jsp结合,渲染的时候可用,常见的返回方式如下。

1、返回ModelAndView

返回ModelAndView时最常见的一种返回结果。需要在方法结束的时候定义一个ModelAndView对象,并对Model和View分别进行设置。

@Controller  
@RequestMapping("/MVCReturn")  
public class SpringMVCReturnController {  

    @RequestMapping(value="/index1",method=RequestMethod.GET)  
    public ModelAndView index(){  
        ModelAndView modelAndView = new ModelAndView("/user/index");  
        modelAndView.addObject("name", "xxx");  
        return modelAndView;  
    }  
//对于ModelAndView构造函数可以指定返回页面的名称,也可以通过setViewName方法来设置所需要跳转的页面;

//采用传统继承的方式:
public class HelloController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mav =new ModelAndView();
        mav.setViewName("hello");   
            //**设置视图名,对应View中jsp文件名(去掉jsp)
        mav.getModel().put("msg", "模型数据");
            //**等价于request.setAttribute("msg","模型数据");底层还是调用这个
        return mav;
    }

}

2.:代表redirect重定向

redirect的特点和servlet一样,使用redirect进行重定向那么地址栏中的URL会发生变化,同时不会携带上一次的request

案例:

public String testController(Model model){

    return "redirect:path";//path代表重定向的地址,如"redirect:hello";

}

3.:代表forward转发

通过forward进行转发,地址栏中的URL不会发生改变,同时会将上一次的request携带到写一次请求中去

案例:

public String testController(Model model){

    return "forward:path";//path代表转发的地址

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值