SpringMVC开发流程

简介: 要点SpringMVC简介搭建环境入门程序全注解J2EE三层使用的注解使用步骤对静态资源的处理传参方式原始方式request.
img_37ff43e92267558c2fbaa70aedbfc133.jpe

要点

  • SpringMVC简介
  • 搭建环境入门程序
  • 全注解
    • J2EE三层使用的注解
    • 使用步骤
    • 对静态资源的处理
  • 传参方式
    • 原始方式request.getParameter()
    • 方法形参与前台参数同名
    • 对象传参
    • 地址栏传参
    • 中文乱码处理
  • 传值方式
    • 通过request.setAttribute()
    • addObject()的方式
    • 直接返回对象
    • 配置视图解析器
    • forward方式
    • redirect方式
    • 通过Model方式
  • 文件上传/下载
    • 文件上传
    • 配置文件上传解析器
    • 上传方法参数MultipartFile
    • 文件下载
  • 拦截器
    • preHandle方法
    • postHandle方法
    • afterCompletion方法
  • 返回JSON格式数据
  • 日期处理
    • 前台往后台传参
    • 后台往前台回显值(JSON)

1.SpringMVC简介

SpringMVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1,Struts2等,在这里暂时就不分析SpringMVC与Struts2的比较了.

2.搭建环境入门程序

需要的jar包(需要什么包添加什么包就不一下全部添加进去了 )
1)添加Spring的核心包


img_e98d8ada597d79baeb4e3c69dd1b8c83.png
图片.png
com.springsource.org.apache.commons.logging-1.1.1.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

添加web.xml文件,使用3.0或以上的版本,3.0以下的对el表达式不是很智能,需要配置isELIgnored="false"
配置前端控制器

 <!--前端控制器/请求分发器-->
<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:application-mvc.xml</param-value>
    </init-param>
    <!--设置优先级-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springMVC</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
img_af366c1224fcdb0e268a9e8a67f2db63.png
图片.png

创建自定义的Controller类,实现Controller接口.复写handleRequest方法

public class HelloWorldController implements Controller {

@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
  //创建自定义Controller类,实现contrller接口复写handleRequest方法
   request.setAttribute("msg","hello!");
   request.getRequestDispatcher("/hello.jsp").forward(request,response);
    return null;
}
}
img_3e1fdcf5ba1071cfce9969570d49b90a.png
图片.png

配置Controller的映射路径,并且交给spring来管理bean

 <!--name请求的映射路径 class:该路径处理类-->
<bean name="/index" class="com.jd.controller.HelloWorldController"></bean>

img_5cd057c67c7ded6d13530c7b9f2b9428.png
图片.png

让框架去找我们自定义的文件名与路径

    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:application-mvc.xml</param-value>
    </init-param>
img_0005349ed03c917bf24555b7fbad39e9.png
图片.png

第一次访问的时候才去加载框架
如果类很多,那么第一次访问就会很慢

 <!--设置优先级-->
 <load-on-startup>1</load-on-startup>

3.使用注解的方式

1.在类打上@Controller注解
2.在方法上添加@RequestMapping注解
3.在springmvc的配置文件上开启注解扫描

public class EmployeeController  {
@RequestMapping("/employee")
public void employee(HttpServletRequest requst, HttpServletResponse response) throws Exception {
    //方法中需要什么对象就写到形参上
    requst.setAttribute("msg","employee!!!!!!!!");
    requst.getRequestDispatcher("/hello.jsp").forward(requst,response);
}
img_2917cebccd1073e214a8c4dd40510754.png
图片.png

必须开启注解扫描

<!--开启注解扫描-->
<context:component-scan base-package="com.jd.controller"></context:component-scan>

@RequestMapping可以打在类上也可以打在方法上
如果是打在类上,必须先加类上的映射,再加方法的映射

img_48384712fe23a0c86de0cc7c68948749.png
图片.png

4.静态资源处理

1./和/的区别
/: 会匹配到url路径(/index),静态资源(
.html,.js等),但是不会匹配到.jsp
/: 会匹配到url路径(/index),静态资源(.html,.js等),也会匹配到.jsp

2.为什么springmvc不能使用/*
Struts2里面是有自定义标签 s:form,jsp文件必须要交有struts2来解析, 所以才会用到/*
SpringMVC是没有自定义标签的,也不能处理jsp文件,所以jsp文件必须交回tomcat来处理,所以才会用/,不过滤jsp文件

3.springmvc匹配到静态资源的时候出现的重定向错误问题
当我们在浏览器访问http://localhost/dept.html,此时的dept.html路径就会被当做url的映射路径来匹配
就会去找@RequestMapping有没有匹配到的路径,如果有的话就把dept.html当做url路径来访问(/dept.???) ?是不会加进去匹配的
也就是说访问dept.html时,只要有dept的路径就可以匹配到

解决方案:
方案 1 交由tomcat来处理,tomcat中的default本来就是处理静态资源的

img_5de07955025b619cacfeace9f187c8bd.png
图片.png

方案2. 配置springmvc处理静态资源(先匹配url是否有相同的路径,如果有就交由方法处理,如果没有才当做静态资源处理)(推荐使用)

 <!--springMVC的静态资源处理配置-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
img_8cf2bd1ffe145a4e1da20e3339dbcc5c.png
图片.png

5.前台往后台传参的方式

@Controller
public class ParamController {

@RequestMapping("/login")
  public void login(HttpServletRequest request){
// 1.原始方式 使用request来获取参数
 System.out.println(request.getParameter("username"));
 System.out.println(request.getParameter("password"));
}

2.使用同名匹配的方式

@RequestMapping("/login")
public void login(String username,String password){
System.out.println(("username"));
System.out.println(("password"));
}

// 3.使用对象的方式

  @RequestMapping("/login")
public void login(User user){
    System.out.println((user));
}

//4.地址栏传参

 @RequestMapping("/delete/{id}")
 public void delete(@PathVariable("id") Long id){
 System.out.print(id);
 }
img_c8f88e6dbf24b8828edc98fd4d519181.png
图片.png

6.解决中文乱码问题(post)

<!--编码过滤器 只对post请求有效-->
<filter>
    <filter-name>characterEncoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>endoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
img_09e7a0fb8c52b8b333088976ddeb3693.png
图片.png

7.后台往前台传值

//后台往前台传值
public class ValueController {
//1.使用原始方式传值
@RequestMapping("/value")
public void value(HttpServletRequest requst, HttpServletResponse response) throws Exception {
    //方法中需要什么对象就写到形参上
    requst.setAttribute("msg", "value!!!!!!!!");
    requst.getRequestDispatcher("/hello.jsp").forward(requst, response);
}

//2.使用ModelAndView对象
@RequestMapping("value1")
public ModelAndView value() throws Exception {
    ModelAndView mv = new ModelAndView();
    //设置属性
    mv.addObject("name", "CoderZS");
    mv.addObject("password", "123");
    User user = new User("zhangsan", "1234");
    mv.addObject("user", user);
    //mv.addObject(user);
    mv.addObject("maYun");//设置默认key为当前对象类型(小写开头)
    mv.addObject("hahaha");//后面设置相同类型的值会覆盖之前的值

    Map map = new HashMap<>();
    map.put("name1", "laowang");
    map.put("password", "12344");
    mv.addAllObjects(map);

    //设置视图
    mv.setViewName("/hello.jsp");
    return mv;
}

//3.直接返回对象
//此时会寻找视图解析器中[前缀+value2+后缀]的页面/WEB-INF/views/value2.jsp
@RequestMapping("/value2")
public User getUser() {
    return new User("CoderZS", "1234");
}

//注意返回String的时候会当做视图解析(推荐使用)
//如果返回的类型是String就会把返回值当做使徒的一部分
//最终去寻找的路径[前缀+返回的值+后缀]
//WEB-INF/views/vvv.jsp
@RequestMapping("/value3")
public String getString(Model model) {
    model.addAttribute("name", "coderZS");
    return "vvv";
}

//4.访问其他路径的文件,不需要用到前后缀
@RequestMapping("/value4")
public String getString() {
    //希望访问其他路径的文件,就不需要用到前缀后缀
    //forward:login.html //请求转发
    return "redirect:login.html";//重定向
}
}

8.文件上传

img_f4b1fd58328168dab3d2e9bd243269c0.png
表单.png
 //文件上传
@RequestMapping("/upload")
//  在方法形参上添加MultipartFile对象来接收(不能使用File来接收了)
public void upload(MultipartFile file) throws Exception {
    System.out.println(file.getName());//提交表单的文件的参数名
    System.out.println(file.getContentType());//文件类型
    System.out.println(file.getOriginalFilename());//提交的文件名
    System.out.println(file.getSize());//文件大小
    //拷贝文件
    FileOutputStream outputStream = new FileOutputStream("/Users/zhangshuai/Desktop/file" + file.getOriginalFilename());
    IOUtils.copy(file.getInputStream(), outputStream);
    //关闭输出流
    outputStream.close();
}
img_e3ad0c613837a4d8fcf66460a2946974.png
图片.png

添加文件上传解析器

 <!--文件上传解析器-->
<bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为1MB -->
    <property name="maxUploadSize">
        <value>1048576</value>
    </property>
</bean>
img_108b2c2e75c72342c1704f28b70a9c35.png
图片.png

9.文件下载

   //文件下载
@RequestMapping("/download")
public  void download(HttpServletResponse response) throws Exception {
    System.out.println("---下载-----");
    //设置下载响应头
    response.setHeader("Content-Disposition","attachment;filename=a.jpg");
    //读取文件
    FileInputStream inputStream=new FileInputStream("/Users/zhangshuai/Desktop/file/1.jpg");
    IOUtils.copy(inputStream, response.getOutputStream());
    //关闭输入流
    inputStream.close();
}
img_e7cc49ee590872f699bd9f2bfd70dc98.png
图片.png

10.注册拦截器

  1. 创建自定义的拦截器类,实现HandlerInterceptor接口
img_fd188304163b1d7802370439c930bec1.png
图片.png

2.注册拦截器

 <!--注册拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <!--排除拦截的路径-->
        <mvc:exclude-mapping path="/login"/>
        <!--拦截处理类-->
        <bean class="com.jd.interceptor.LoginInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
img_eb41a4eda340cfe304d75c20c122ddc4.png
图片.png

11.返回json格式

在方法的返回值上直接声明要返回的类型,并且加上@ResponseBody注解

需要添加json解析依赖包

img_ea5176162c26589356e175eb74b12ca3.png
图片.png
//返回json格式
// 1.在方法的返回值上直接声明要返回的类型,并且加上@ResponseBody注解
 @Controller
public class JsonController {
@RequestMapping("/json")
@ResponseBody
public User json() {
    User user = new User("CoderZS", "1234");
    return user;
}

@RequestMapping("/json1")
@ResponseBody
public List<User> json1() {
    User user = new User("CoderZS", "1234",new Date());
    List list = new ArrayList<>();
    list.add(user);
    return list;
}

//2.使用ObjectMapper
public static void main(String[] args) throws Exception {
    User user = new User("CoderZS", "1234");
    //转成json字符串的工具
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(user);
    System.out.println(json);
}
}

12.日期处理

后台往前台传json值时(包含日期)

默认输出的是毫秒值,需要使用特定的格式

解决方案:
方案1:在属性上添加@JsonFormat注解,注意要添加时区

img_fa03025be6f063db6373d278185f2641.png
图片.png

方案2: 在总配置文件添加相关配置

  <mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                    <property name="dateFormat">
                        <bean class="java.text.SimpleDateFormat">
                            <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
                        </bean>
                    </property>
                </bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
前台往后台传参时(包含日期)

1.在日期参数上添加@DateTimeFormat注解

img_3f510106c4e597d254576d94853b3f21.png
图片.png

2.在Controller上添加initBinder方法

 @InitBinder
public void initBinder(WebDataBinder binder){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    sdf.setLenient(false);
    binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
}

如果两种都有,会使用initBinder方法

13.图解SpringMVC执行流程

img_70f397903c5984c3950d17bc8d21e1a2.png
执行流程.png
img_49b52d3dbab7a90872ac92e4e92908ef.png
SpringMVC执行流程.png

点击查看--->SpringMVC执行流程及原理

目录
相关文章
|
前端开发 JavaScript 数据处理
Yii2.0框架的MVC架构是如何设计的?它的流程是什么样的?
Yii2.0框架的MVC架构是如何设计的?它的流程是什么样的?
102 0
|
存储 运维 Dubbo
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
> Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双 11 基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实践和统一标准,同时将规模化实践经验与技术创新贡献开源社区,极大的推动了开源技术与标准的发展。 > 本文
418 0
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
|
Java 应用服务中间件 数据库
Web阶段:第十一章:JavaEE项目的三层架构
Web阶段:第十一章:JavaEE项目的三层架构
116 0
Web阶段:第十一章:JavaEE项目的三层架构
|
前端开发 JavaScript Java
基于javaweb(springboot)汽车配件管理系统设计和实现以及文档报告
主要功能: 系统主要设计采用Java语言开发、采用springboot为后台框架、数据库框架采用mybatis、前端采用jquery、layui框架等 主要模块设计如下: 1.用户模块管理:用户登录、用户的查询、添加、删除操作、 2.菜单模块管理:页面菜单的展示、添加操作、修改操作、删除
243 0
基于javaweb(springboot)汽车配件管理系统设计和实现以及文档报告
|
应用服务中间件
Servlet开发初体验(验错过程)
Servlet开发初体验(验错过程)
|
Java 应用服务中间件 Spring
【重温SSM框架系列】4 - Spring集成web环境(三层结构和配置监听器)
【重温SSM框架系列】4 - Spring集成web环境(三层结构和配置监听器)
162 0
【重温SSM框架系列】4 - Spring集成web环境(三层结构和配置监听器)
|
前端开发 Java 关系型数据库
JavaWeb实现smbms项目核心功能
SMBMS 数据库: 项目如何搭建? 考虑使用不使用Maven?依赖,Jar 1、项目搭建准备工作 搭建一个maven web项目 配置Tomcat 测试项目是否能够跑起来 导入项目中会遇到的jar包; jsp,Servlet,mysql驱动,jstl,standard... 创建项目包结构 编写实
|
Web App开发 前端开发 .NET
【ABP框架系列学习】模块系统(4)
原文:【ABP框架系列学习】模块系统(4) 0.引言 ABP提供了构建模块和通过组合模块以创建应用程序的基础设施。一个模块可以依赖于另外一个模块。通常,程序集可以认为是模块。如果创建多个程序集的应用程序,建议为每个程序集创建模块定义。
1535 0
|
Java 数据库 Spring
Activiti 6.x【2】activiti6.0 基本流程讲解与开发前奏
版权声明:转载注明出处就OK的说,有些东西会转载,都会注明的说= =如果有冒犯麻烦见谅 https://blog.csdn.net/Pan1458689676/article/details/82560185 ...
4878 0