SpringMvc

孤街醉人 提交于 2020-01-28 23:44:09

三层结构介绍

  表现层

* 也就是我们常说的web 层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http 协议请求web 层,web 需要接收 http 请求,完成 http 响应。

* 表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。

* 表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。

表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)

   业务层

* 也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web 层依赖业务层,但是业务层不依赖 web 层。

业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的, 事务应该放到业务层来控制)

   持久层

* 也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的。

SpringMvc是什么?

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring 的 Spring MVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等

SpringMvc整体结构

 

 开发环境:

本案例使用开发环境:

Jdk:jdk1.8

IDE:Oxygen

Tomcat:apache-tomcat-8.5.x

Springmvc:5.0.7

编写简单的springmvc程序:

package com.kkb.springmvc.controller;

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

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

import com.kkb.springmvc.po.Item;

/***
 * 处理器的开发方式有多种,比如实现HttpRequestHandler接口、Controller接口的方式,还有注解的方式
 * 企业中使用的一般来讲都是注解的方式 注解的方式,主要有两个注意事项:
 * 类上加上@Controller注解(必须是Controller,可以通过源码找到答案) 类上或者方法上面要加上@RequestMapping注解(必须的)
 * 
 * @author think
 *
 */
@Controller
public class ItemController {

    // @RequestMapping此时填写的是url
    // ModelAndView:model表示的是数据模型,view就是最终要展示给用户的视图
    @RequestMapping("queryItem")
    public ModelAndView queryItem() {

        // 查询数据库,用静态数据模拟
        List<Item> itemList = new ArrayList<>();

        // 商品列表
        Item item_1 = new Item();
        item_1.setName("联想笔记本_3");
        item_1.setPrice(6000f);
        item_1.setDetail("ThinkPad T430 联想笔记本电脑!");

        Item item_2 = new Item();
        item_2.setName("苹果手机");
        item_2.setPrice(5000f);
        item_2.setDetail("iphone6苹果手机!");

        itemList.add(item_1);
        itemList.add(item_2);

        ModelAndView mvAndView = new ModelAndView();

        // 设置数据模型,相当于request的setAttribute方法,实质上,底层确实也是转成了request(暂时这样理解)
        // 先将k/v数据放入map中,最终根据视图对象不同,再进行后续处理
        mvAndView.addObject("itemList", itemList);

        // 设置视图(逻辑路径)
        mvAndView.setViewName("item/item-list");
        // mvAndView.setViewName("/WEB-INF/jsp/item/item-list.jsp");

        return mvAndView;
    }
}
<?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:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 处理器类的扫描 -->
    <context:component-scan
        base-package="com.kkb.springmvc.controller" />

    <!--注解映射器 @Controller和@RequestMapping组合这种方式的注解映射的解析 -->
    <!-- <bean -->
    <!-- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" 
        /> -->
    <!--注解适配器 -->
    <!-- <bean -->
    <!-- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" 
        /> -->
    
    <!-- 配置注解的适配器和映射器,同时还注入了很多其他的bean -->
    <mvc:annotation-driven/>
    
    <!-- 显式的配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <!-- 学习前置条件 -->
    <!-- 问题1:web.xml中servelet、filter、listener、context-param加载顺序 -->
    <!-- 问题2:load-on-startup标签的作用,影响了servlet对象创建的时机 -->
    <!-- 问题3:url-pattern标签的配置方式有四种:/dispatcherServlet、 /servlet/*  、*.do  、/ ,以上四种配置,加载顺序是如何的-->
    <!-- 问题4:url-pattern标签的配置为/*报错,原因是它拦截了JSP请求,但是又不能处理JSP请求。为什么配置/就不拦截JSP请求,而配置/*,就会拦截JSP请求-->
    <!-- 问题5:配置了springmvc去读取spring配置文件之后,就产生了spring父子容器的问题 -->
    
    <!-- 配置前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 设置spring配置文件路径 -->
        <!-- 如果不设置初始化参数,那么DispatcherServlet会读取默认路径下的配置文件 -->
        <!-- 默认配置文件路径:/WEB-INF/springmvc-servlet.xml -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!-- 指定初始化时机,设置为2,表示Tomcat启动时,DispatcherServlet会跟随着初始化 -->
        <!-- 如果不指定初始化时机,DispatcherServlet就会在第一次被请求的时候,才会初始化,而且只会被初始化一次 -->
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- URL-PATTERN的设置 -->
        <!-- 不要配置为/*,否则报错 -->
        <!-- 通俗解释:/*,会拦截整个项目中的资源访问,包含JSP和静态资源的访问,对于静态资源的访问springMVC提供了默认的Handler处理器 -->
        <!-- 但是对于JSP来讲,springmvc没有提供默认的处理器,我们也没有手动编写对于的处理器,此时按照springmvc的处理流程分析得知,它短路了 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- <servlet> -->
    <!-- <servlet-name>sss</servlet-name> -->
    <!-- <servlet-class>sss</servlet-class> -->
    <!-- </servlet> -->
    <!-- <servlet-mapping> -->
    <!-- <servlet-name>sss</servlet-name> -->
    <!-- <url-pattern>/sss</url-pattern> -->
    <!-- </servlet-mapping> -->
</web-app>

SSM框架的整合

配置版:

1.添加依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.13.RELEASE</version>
</dependency>
2.创建Student实体类
package cn.tina;
public class Student {
    private int stuNo;
    private String name;
    public int getStuNo() {
        return stuNo;
    }
    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
3.编写spring核心配置文件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"
       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">
    <bean id="student" class="cn.tina.Student">
        <property name="name" value="张三"/>
        <property name="stuNo" value="1001"/>
    </bean>
</beans>

4.编写测试类
public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = (Student) context.getBean("student");
    System.out.println(student.getName()+"---"+student.getStuNo());
}

注解版:

//添加依赖
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.1.9.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.7</version>
    </dependency>
    <dependency>
        <groupId>aopalliance</groupId>
        <artifactId>aopalliance</artifactId>
        <version>1.0</version>
    </dependency>

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.1</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>

    <dependency>
        <groupId>com.hynnet</groupId>
        <artifactId>oracle-driver-ojdbc6</artifactId>
        <version>12.1.0.1</version>
    </dependency>

    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>commons-pool</groupId>
        <artifactId>commons-pool</artifactId>
        <version>1.6</version>
    </dependency>

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.1</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>4.1.9.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>3.0-alpha-1</version>
        <!-- 打包的时候忽略,因为tomcat中有,重复的包会冲突-->
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.6</version>
    </dependency>

    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>
</dependencies>
//编写实体类
package cn.entity;

public class Grade {
    private int gradeId;
    private String gradeName;
    @Override
    public String toString() {
        return "Grade{" +
                "gradeId=" + gradeId +
                ", gradeName='" + gradeName + '\'' +
                '}';
    }
    public int getGradeId() {
        return gradeId;
    }
    public void setGradeId(int gradeId) {
        this.gradeId = gradeId;
    }
    public String getGradeName() {
        return gradeName;
    }
    public void setGradeName(String gradeName) {
        this.gradeName = gradeName;
    }
}
//编写Mapper
package cn.dao;

import cn.entity.Grade;
import java.util.List;

public interface GradeMapper {
    public List<Grade> getListGrade();
    public  int addGrade(Grade grade);
}
//编写Mapper.xml 注意放入resource下同名文件夹
<?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">

<!-- SQL映射文件 -->
<mapper namespace="cn.dao.GradeMapper">

    <select id="getListGrade" resultType="Grade">
           select * from grade
    </select>
    <insert id="addGrade" parameterType="Grade">
        insert into grade(gradeId,gradeName)values(#{gradeId},#{gradeName})
    </insert>
</mapper>  
//编写Service
package cn.service;

import cn.entity.Grade;
import java.util.List;
public interface GradeService {
    public List<Grade> getListGrade();
    public  int addGrade(Grade grade);
}

编写实现类:
package cn.service.impl;

import cn.dao.GradeMapper;
import cn.entity.Grade;
import cn.service.GradeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service//默认bean的名称与类名同名,只是首字母改为小写
public class GradeServiceImpl implements GradeService {

    @Autowired//可以从spring容器中取出gradeMapper组件
            GradeMapper gradeMapper;

    @Override
    public List<Grade> getListGrade() {
        return gradeMapper.getListGrade();
    }

    @Transactional //添加事务注解
    public int addGrade(Grade grade) {
        int cn = gradeMapper.addGrade(grade);
       // int  i=1/0; //这个错误不能去捕获 让spring容器处理 会回滚数据
        return cn;
    }
}
//编写Spring配置类
package cn.config;

import org.apache.commons.dbcp.BasicDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@ComponentScan(value = "cn")
@EnableTransactionManagement//开启注解式事务
@EnableAspectJAutoProxy //开启注解式aop
public class SpringConfig {

    @Bean//在spring中注入一个数据源
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        //mysql--连接
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setPassword("root");
        dataSource.setUsername("root");
        dataSource.setUrl("jdbc:mysql://localhost:3306/myschool");
      /*  dataSource.setUsername("system");
        dataSource.setPassword("root");
        dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
        dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");*/
        return dataSource;
    }

    @Bean //设置session工厂
    public SqlSessionFactoryBean sqlSessionFactory( DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setTypeAliasesPackage("cn.entity");
        //如果命名规范,且在同一个包中,可省略
//      ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//      try {
//  sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:cn/dao/*Dao.xml"));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        return sqlSessionFactoryBean;
    }

    @Bean//扫描mapper 为它生成mapper的实现类
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("cn.dao");
        return mapperScannerConfigurer;
    }
  //配置事务管理器
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource ){
        return new DataSourceTransactionManager(dataSource);
    }
}
//先编写main方法,测试spring和myabtis是否整合完成
public static void main(String[] args) {
      AnnotationConfigApplicationContext context =
 new AnnotationConfigApplicationContext(SpringConfig.class);
GradeService gradeService = 
(GradeService) context.getBean("gradeServiceImpl");
Grade grade=new Grade();
grade.setGradeId(5);
grade.setGradeName("444");
int cn =gradeService.addGrade(grade);
System.out.println(cn+"---------------");
}
//编写Controller
package cn.controller;

import cn.entity.Grade;
import cn.service.GradeService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.List;

@Controller
public class GradeController {

    @Resource
    GradeService gradeService;

    @RequestMapping("/")
    public String toIndex(){
        return "redirect:/index";
    }
    @RequestMapping("/add")
    public  String add(Grade grade, Model model){
         int cn =gradeService.addGrade(grade);
         model.addAttribute("msg","新增成功");
        return "forward:/index";
    }

    @RequestMapping("/index")
    public String index(Model model){
        List<Grade> list= gradeService.getListGrade();
        model.addAttribute("list",list);
        return "index";
    }
}
//编写全局异常处理类
//这个注解可以对全局异常,或者数据类型转换
@ControllerAdvice
public class MyAdvice {
    @ExceptionHandler
    public String handlerException(Exception e, HttpServletRequest request)   {
        request.setAttribute("msg", "异常:" + e.getMessage());
        return "error";
    }
    /* @InitBinder  //使用配置转换器方式
 public void web(WebDataBinder binder) {
     binder.registerCustomEditor(Date.class,
             new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
 }*/
}
//编写前台到后台的日期转换器
public class StringFormatByDate implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sf.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
            return  null;
        }
    }
}
//配置拦截器
public class MyInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("进入了拦截。。。。。");
        return true;
    }
}
//编写MVC配置类
@Configuration
@EnableWebMvc //相当于开启注解方式
@ComponentScan(value = "cn.controller")
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override //视图解析器 注意:views文件夹在resource下
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/WEB-INF/classes/views/", ".jsp");
    }
    @Override//不能直接使用add.jsp 配置一个跳转
    public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/toAdd").setViewName("add");
   }

    @Override //静态资源映射 注意:static文件夹在resources下
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }

    @Override  //json前台到后台的问题:中文编码和日期问题
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        fastJsonHttpMessageConverter.setCharset(Charset.forName("utf-8"));
     fastJsonHttpMessageConverter.setFeatures(SerializerFeature.WriteDateUseDateFormat);
        converters.add(fastJsonHttpMessageConverter);
    }

    @Override //注册 :前台到后台的日期问题
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringFormatByDate());
    }
    @Override //配置拦截器
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }
}
//取代在web.xml配置中的启动spring和mvc
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override//相当于在以前web.xml中配置的读取applicationContext.xml
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};//用于Spring的配置
    }

    @Override//相当于在以前web.xml中配置的读取springmvc-servlet.xml
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{MvcConfig.class};//专门用于MVC的配置
    }

    @Override
    protected String[] getServletMappings() { // /处理请求,不拦截jsp /* 会拦截jsp
        return new String[]{"/"};
    }

    /* 添加过滤器*/
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return new Filter[]{characterEncodingFilter};
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!