三层结构介绍
表现层:
* 也就是我们常说的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};
}
}
来源:https://www.cnblogs.com/wnlsq/p/12239164.html