Java Web - SpringMVC(1)


目录

  • Java Web - SpringMVC(1)
    • 4.1 返回字符串逻辑视图
    • 4.2 void原始ServletAPI
    • 4.3 ModelAndView
    • 4.4 Session 域共享数据
    • 4.5 静态资源访问开启
    • 3.1 请求参数类型
    • 3.1.1 基本数据类型参数
    • 3.1.2 对象类型参数
    • 3.1.3 数组类型参数
    • 3.1.4 集合类型参数
    • 3.1.5 自定义类型转换器
    • 3.1.6 相关注解使用
    • 3.1.7 获取servlet
    • 2.1 SpringMVC 执行流程 (基于组件)
    • 2.2  SpringMVC 注解详解
    • 1.1 Spring MVC 简介
    • 1.2 Spring MVC 使用快速入门
    • 1.3 执行流程(基于web工程)
    • 1 SpringMVC 基本应用
    • 2 SpringMVC 组件概述
    • 3 SpingMVC 请求
    • 4 SpirngMVC 响应


1 SpringMVC 基本应用

1.1 Spring MVC 简介

基于 Java 的实现 MVC 设计模式的轻量级 Web 框架

通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现 任何接口。同时它还支持 RESTful 编程风格的请求

SpringMVC的框架就是封装了原来Servlet中的共有行为;例如:参数封装,视图转发等

1.2 Spring MVC 使用快速入门

  • 创建Java web 项目

Java Web - SpringMVC(1)_Java Web

// 1 导入Spring-MVC 入门基本坐标 spring-web mvc, servlet-api, jsp-api

// 2 创建Spring-MVC 核心配置文件,并添加扫描的包目录 添加mvc和context 文件头, 扫描包只需要扫描controller层
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
    
// 3 在 web.xml 中配置前端控制器 DispathcerServlet, 主要配置contextConfigLocation读取spring-mvc核心配置文件,设置该servlet项目加载创建,映射路径(/)该路径匹配除了.xx外的所有访问路径
    
    <servlet>
	<servlet-name>dispatcherServlet</servlet-name>
	<servletclass>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>2</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

// 4 编写contoller 类,@Controller标记类 @RequestMapping("/xx") 返回为String(访问路径)的方法
@Controller
public class UserController {
	@RequestMapping("/quick")
	public String quick() {
		System.out.println("quick running.....");
		return "/WEB-INF/pages/success.jsp";
    }

1.3 执行流程(基于web工程)

Java Web - SpringMVC(1)_Java Web_02

2 SpringMVC 组件概述

2.1 SpringMVC 执行流程 (基于组件)

Java Web - SpringMVC(1)_Java Web_03

// 执行流程 (基于组件)
1. 用户发送请求至前端控制器DispatcherServlet。
2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成) HandlerExecutionChain 一并返回给DispatcherServlet。
4. DispatcherServlet调用HandlerAdapter处理器适配器。
5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6. Controller执行完成返回ModelAndView。
7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9. ViewReslover解析后返回具体View。
10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11. DispatcherServlet将渲染后的视图响应响应用户。
    

// 组件分析
// 1. 前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。

// 2. 处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器(自己编写的controller类),SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

// 3. 处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

// 4. 处理器:Handler【**开发者编写**】
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到Handler。由Handler 对具体的用户请求进行处理。

// 5. 视图解析器:ViewResolver
View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名(拼接前缀后缀),即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

    
// 6. 视图:View 【**开发者编写**】
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面
    
springmvc中的三大组件是什么?
    处理器映射器:HandlerMapping,处理器适配器:HandlerAdapter,视图解析器:ViewResolver
    
// 显示配置三大组件 - springmvc核心配置文件中 - 添加mvc头文件
    <!--处理器映射器和处理器适配器功能增强 支持json的读写-->
	<mvc:annotation-driven></mvc:annotation-driven>
        
    <!--视图解析器-->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

2.2  SpringMVC 注解详解

// @Controller
	SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要在核心配置文件中配置注解扫描
        
// @RequestMapping
        建立请求 URL 和处理请求方法之间的对应关系
        
        // 注解位置:
        // 类上:请求URL的第一级访问目录,模块化
        /user/add ...
        
        // 方法上:请求URL的第二级访问目录
        // 注解属性
		1.value:用于指定请求的URL。它和path属性的作用是一样的
		2.method:用来限定请求的方式
		3.params:用来限定请求参数的条件
        	params={"accountName"} 表示请求参数中必须有accountName

3 SpingMVC 请求

3.1 请求参数类型

// 客户端请求参数的格式:name=value&name=value...

// SpringMVC 可以接收以下4种类型参数:
	- 基本类型参数
    - 对象类型参数
    - 数组类型参数
    - 集合类型参数
3.1.1 基本数据类型参数
// Controller 类业务方法的参数名称与请求参数的name相同,参数可以自动映射匹配并类型转换(String 转为其他类型)

// JSP 获取绝对路径的方法
 - ${pageContext.request.contextPath} 等价于 <%=request.getContextPath()%> //取出部署的应用程序名或者是当前的项目名称

// 生成基本数据类型测试Jsp JSP绝对路径后直接拼接映射路径/quick2 访问webapp下的资源时直接访问/xxx.jsp    
<a href="${pageContext.request.contextPath}/quick2?id=1&username=杰克">
基本类型
</a>

@RequestMapping("/quick2")
public String quick2(Integer id,String username) { //参数与请求参数name相同
System.out.println(id); 
System.out.println(username);
return "success";
}
3.1.2 对象类型参数
// Controller 类业务方法参数POJO的属性名和请求参数的name一致,参数会自动映射匹配

// Jsp 添加from 表单,POST提交
	<form action="${pageContext.request.contextPath}/quick3">
        <input name="id" type="text"><br>
        <input name="username" type="text"><br>
        <input type="submit" value="POJO类型">
    </form>
        
// POST 提交中文会乱码,需要web.xml 中设置中文乱码过滤器 初始参数encoidng设置并拦截所有请求
        
<filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>  
    
// 创建实体类,属性名称对应请求参数name,方法参数为该POJO类  

	@RequestMapping("/quick3")
    public String quick(User user) {
        System.out.println(user);
        return "success";
    }
3.1.3 数组类型参数
// Controller 业务方法参数为[]数组类型且参数名与表单中提交checkbox name一致

// JSP 添加form 表单
   <form action="${pageContext.request.contextPath}/quick4">
        <input type="checkbox" name="ids" value="1">1<br>
        <input type="checkbox" name="ids" value="2">2<br>
        <input type="checkbox" name="ids" value="3">3<br>
        <input type="checkbox" name="ids" value="4">4<br>
        <input type="submit" value="数组类型">
    </form>
       
// 
	@RequestMapping("/quick4")
    public String quick4(Integer[] ids) {
        System.out.println(Arrays.toString(ids));
        return "success";
    }
3.1.4 集合类型参数
// 使用集合类型时必须将集合参数包封装到POJO中

// Controller 方法参数中传入POJO对象,POJO对象中封装List<> 集合和 Map<K,V> 集合,名称和参数name一致

// JSP 对于List 
	<form action="${pageContext.request.contextPath}/quick5">
        <input type="text" name="userList[0].id" placeholder="编号"><br>
        <input type="text" name="userList[0].username" placeholder="姓名"><br>

        <input type="text" name="userList[1].id" placeholder="编号"><br>
        <input type="text" name="userList[1].username" placeholder="姓名"><br>

        <input type="text" name="userMap['u1'].id" placeholder="编号"><br>
        <input type="text" name="userMap['u1'].username" placeholder="姓名"><br>

        <input type="text" name="userMap['u2'].id" placeholder="编号"><br>
        <input type="text" name="userMap['u2'].username" placeholder="姓名"><br>

        <input type="submit" value="userList">
    </form>
        
        
	@RequestMapping("/quick5")
    public String quick5(POJO pojo) {
        System.out.println(pojo);
        return "success";
    }
3.1.5 自定义类型转换器
// 日期类型 格式要求为 yyyy/MM/dd

// 编写自定义类型转换器类,实现Converter<String, Date>接口,将String转换为目标类
public class DataConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = dateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

// spirngmvc核心配置文件中配置converter
	<bean id="conversionService" 	class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.lagou.converter.DataConverter"></bean>
            </set>
        </property>
    </bean>

    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
        
// JSP 
	<form action="${pageContext.request.contextPath}/quick6">
        <input type="text" name="date"><br>
        <input type="submit" value="日期">
    </form>     
        
 	@RequestMapping("/quick6")
    public String quick6(Date date) {
        System.out.println(date);
        return "success";
    }
3.1.6 相关注解使用
// @RequestParam
请求的参数name名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定
    
@RequestParam() 注解
- defaultValue 设置参数默认值
- name 匹配页面传递参数的名称
- required 设置是否必须传递参数,默认值为true;如果设置了默认值,值自动改为false

<a href="${pageContext.request.contextPath}/user/findByPage?pageNo=2">
分页查询
</a>

@RequestMapping("/findByPage")
public String findByPage(@RequestParam(name = "pageNo", defaultValue = "1")
Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) {
System.out.println(pageNum); // 2
System.out.println(pageSize); // 5
return "success";
}    
    
// @RequestHeader
获取请求头的数据
@RequestMapping("/requestHead")
public String requestHead(@RequestHeader("cookie") String cookie) {
System.out.println(cookie);
return "success";
}
    
// @CookieValue 获取cookie中数据
@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String jesessionId) {
System.out.println(jesessionId);
return "success";
}
3.1.7 获取servlet
// springmvc 支持原始servlet 对象参数注入使用

@RequestMapping("/servletAPI")
public String servletAPI(HttpServletRequest request, HttpServletResponse
response, HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "success";
}

4 SpirngMVC 响应

// 页面跳转
	- 返回字符串逻辑视图
	- void原始ServletAPI
	- ModelAndView
        
// 返回数据
	- 直接返回字符串数据
	- 将对象或集合转为json返回

4.1 返回字符串逻辑视图

// 直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转到指定页面

@RequestMapping("/returnString")
public String returnString() {
return "success";
}

4.2 void原始ServletAPI

// request、response对象实现响应
@RequestMapping("/returnVoid")
public void returnVoid(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 1.通过response直接响应数据
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("拉勾网");
----------------------------------------
request.setAttribute("username", "拉勾教育");
// 2.通过request实现转发
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,
response);
----------------------------------------
// 3.通过response实现重定向 不能直接访问WEB-INF下的资源
response.sendRedirect(request.getContextPath() + "/index.jsp");
}

// 转发
	- 返回字符串逻辑视图实现页面的跳转,这种方式其实就是请求转发
	- 请求转发,既可以转发到jsp,也可以转发到其他的控制器方法        
        
	// forward 转发 路径必须写成实际视图url,不能写逻辑视图,相当于
        request.getRequestDispatcher("url").forward(request,response)
        
// 重定向
	- 可以不写虚拟目录,springMVC框架会自动拼接,并且将Model中的数据拼接到url地址上  

@RequestMapping("/redirect")
public String redirect(Model model) {
model.addAttribute("username", "拉勾教育");
return "redirect:/index.jsp";
}

4.3 ModelAndView

// 1 Controller中方法创建并返回ModelAndView对象,并且设置视图名称

@RequestMapping("/returnModelAndView1")
public ModelAndView returnModelAndView1() {
/*
Model:模型 作用封装数据
View:视图 作用展示数据
*/
ModelAndView modelAndView = new ModelAndView();
//设置模型数据
modelAndView.addObject("username", " lagou");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}

// 2 Controller中方法形参上直接声明ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面

@RequestMapping("/returnModelAndView2")
public ModelAndView returnModelAndView2(ModelAndView modelAndView) {
//设置模型数据
modelAndView.addObject("username", "lagou");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}

4.4 Session 域共享数据

//@SessionAttributes 只能定义在类上
// 多个请求之间共用数据,则可以在控制器类上标注一个 @SessionAttributes,配置需要在session中存放的数据范围,Spring MVC将存放在model中对应的数据暂存到 HttpSession 中

@Controller
@SessionAttributes("username") //向request域存入的key为username时,同步到session域中
public class UserController {
@RequestMapping("/forward")
public String forward(Model model) {
model.addAttribute("username", "jack");
return "forward:/WEB-INF/pages/success.jsp";
}
@RequestMapping("/returnString")
public String returnString() {
return "success";
}
}

// success.jsp 
${username} EL表达式两次访问都可以得到值

4.5 静态资源访问开启

// 静态资源如jquery文件,当SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是 / 代表对所有的静态资源都进行处理操作,这样就不会执行Tomcat内置的DefaultServlet处理

// 放行指定静态资源
<!--在springmvc配置文件中指定放行资源-->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/img/**" location="/img/"/>
    
// 方式二
<!--在springmvc配置文件中开启DefaultServlet处理静态资源-->
<mvc:default-servlet-handler/>