SpringMvc


三層結構介紹

  表現層

* 也就是我們常說的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};
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM