SpringMVC基础学习

SpringMVC

流程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SnycNcz4-1592493397355)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20191206165911747.png)]

springmvc是将原本web服务器一体化的操作,改变为多个组件模块,使得各个组件都有各自的功能,提高的效率,降低的耦合性。

web服务器启动时会—加载web配置(创建前端控制器,过滤器,监听器创建)–读取springmvc.xml(扫描controller类、配置视图解析器、自定义类型转换,拦截器,异常处理器)

1.入门案例

1.导入依赖

2.web.xml配置

<!-- SpringMVC的核心控制器 --> 
<servlet> 
    <servlet-name>dispatcherServlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 --> 
    <init-param>
		<param-name>contextConfigLocation</param-name> 
        <param-value>classpath:springmvc.xml</param-value>
    </init-param> 
    <!-- 配置servlet启动时加载对象 --> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping>

3.编写SpringMVC.xml

<?xml version="1.0" encoding="UTF-8"?> <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"> 
    <!-- 配置spring创建容器时要扫描的包 --> 
    <context:component-scan base-package="com.itheima"></context:component-scan> 
    <!-- 配置视图解析器 --> 
    <bean id="viewResolver" 	  class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
        <property name="prefix" value="/WEB-INF/pages/"></property> 
        <property name="suffix" value=".jsp"></property>
    </bean> 
    <!-- 配置spring开启注解mvc的支持-->  
	<mvc:annotation-driven></mvc:annotation-driven>
</beans> 

4.编写index.jsp和HelloController控制器类

2.过滤器编写

<!-- 配置过滤器,解决中文乱码的问题 --> 
<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>

3.自定义类型转换

public class StringToDateConverter implements Converter<String, Date>{
    /*** 进行类型转换的方法 */ 
    public Date convert(String source) { 
        // 判断 
        if(source == null) { throw new RuntimeException("参数不能为空"); 
                           }
try {DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); 
     // 解析字符串 
     Date date = df.parse(source); return date; } 
        catch (Exception e) 
        { throw new RuntimeException("类型转换错误"); } 
    } }

注册转换器

<!-- 注册自定义类型转换器 --> 
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> 
    <property name="converters"> 
        <set><bean class="cn.itcast.utils.StringToDateConverter"/> </set> 
    </property> 
</bean>
<!-- 开启Spring对MVC注解的支持 --> 
<mvc:annotation-driven conversion-service="conversionService"/>

4.常用注解

@ RequestParam 获取请求参数

@ RequestBody 获取请求体内容

@ PathVariable 获取占位符

@RequestHeader 获取指定名称请求头的值

@ CookieValue 获取指定名称Cookie的值

@ ModelAttribute

  1. 出现在方法上:表示当前方法会在控制器方法执行前线执行。

  2. 出现在参数上:获取指定的数据给参数赋值。

    (我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数

    据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题)

    加在有返回值的方法上,此方法会优先控制器方法执行,并且返回值会传递给控制器方法
    
    1.在没有返回值方法上,参数设置一个Map可以存储数据到model中
    @ModelAttribute
    public void showModel(String username,Map<String,User> map) {
    //模拟去数据库查询
    User user = findUserByName(username);
    System.out.println("执行了 showModel 方法"+user);
    map.put("abc",user);
    }
    2.然后在使用到参数上,获取model中的值,赋值给参数
    @RequestMapping("/updateUser")
    public String testModelAttribute(@ModelAttribute("abc")User user) {
    System.out.println("控制器中处理请求的方法:修改用户:"+user);
    return "success"; }
    

@ResponseBody

该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的
数据如:json,xml 等,通过 Response 响应给客户端

要求:
Springmvc 默认用 MappingJacksonHttpMessageConverter 对 json 数据进行转换,需要加入
jackson 的包。

5.参数的绑定

规则

1. 绑定机制
	1. 表单提交的数据都是k=v格式的 username=haha&password=123
	2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
	3. 要求:提交表单的name和参数的名称是相同的

2. 支持的数据类型
	1. 基本数据类型和字符串类型
	2. 实体类型(JavaBean) 
	3. 集合数据类型(List、map集合等)
	
使用要求:
    基本类型和字符串类型:提交的表单name和参数名
    
    实体类型:要求bean属性名称和提交的name一致
    
    集合数据类型:
      集合类型的请求参数必须在POJO中,表格中请求参数名称要和POJO类中的属性名相同
    	1.给List集合中的元素赋值,使用下标List[0].age
    	2.给Map集合中的元素赋值,使用键值 accountMap['one'].name"
      接收的是JSON格式的参数@RequestBody

6.响应数据

1.返回字符串类型

可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

2.返回void

没有返回值,默认请求后。页面会跳转到,请求地址.jsp的这个页面,需要跳转页面可以使用

请求转发(路径需要设置相对路径,因为视图解析器没办法解析),

重定向(要用项目名称拼接字符串地址),

或者使用输出流直接输出信息到页面中(需要注意到中文乱码的问题)

3.返回ModelAndView

使用ModelAndView,可以通过addObject()存储对象,使用setViewName(),设置跳转页面
对象会存储到request中

4.forward 转发

controller 方法在提供了 String 类型的返回值之后,默认就是请求转发。我们也可以写成:
return "forward:/WEB-INF/pages/success.jsp";

5.Redirect 重定向

contrller 方法提供了一个 String 类型返回值之后,它需要在返回值里使用:redirect:
return "redirect:testReturnModelAndView";
(redirect后面的数据,就如同http://localhost:8080后的数据)
它相当于“response.sendRedirect(url)”。需要注意的是,如果是重定向到 jsp 页面,则 jsp 页面不
能写在 WEB-INF 目录中,否则无法找到。

7.SpringMVC实现文件上传

要求

A form 表单的 enctype 取值必须是:multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型
B method 属性取值必须是 Post
C 提供一个文件选择域<input type=”file” />

分析

当 form 表单的 enctype 取值不是默认值后,request.getParameter()将失效。 enctype=”application/x-www-form-urlencoded”时,form 表单的正文内容是:
key=value&key=value&key=value
当 form 表单的 enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成:
每一部分都是 MIME 类型描述的正文
-----------------------------7de1a433602ac 分界符
Content-Disposition: form-data; name="userName" 协议头

使用第三方组件实现

使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和
commons-io。commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它工作时需要 commons-io 包的支持。

传统步骤

一、导入jar包

二、编写jsp页面

三、编写控制器

@Controller("fileUploadController")
public class FileUploadController {
/**
* 文件上传
*/
@RequestMapping("/fileUpload")
public String testResponseJson(String picname,MultipartFile 
uploadFile,HttpServletRequest request) throws Exception{
//定义文件名
String fileName = "";
//1.获取原始文件名
String uploadFileName = uploadFile.getOriginalFilename();
//2.截取文件扩展名
String extendName = 
uploadFileName.substring(uploadFileName.lastIndexOf(".")+1, 
uploadFileName.length());
//3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
//4.判断是否输入了文件名
if(!StringUtils.isEmpty(picname)) {
fileName = uuid+"_"+picname+"."+extendName; }else {
fileName = uuid+"_"+uploadFileName; }
System.out.println(fileName);
//2.获取文件路径
ServletContext context = request.getServletContext();
String basePath = context.getRealPath("/uploads");
//3.解决同一文件夹中文件过多问题
String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//4.判断路径是否存在
File file = new File(basePath+"/"+datePath);
if(!file.exists()) {
file.mkdirs();
}
//5.使用 MulitpartFile 接口中方法,把上传的文件写到指定位置
uploadFile.transferTo(new File(file,fileName));
return "success"; } }

四、配置文件解析器

<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" <!-- id 的值是固定的-->
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为 5MB -->
<property name="maxUploadSize"> <value>5242880</value>
</property>
</bean>
注意:
文件上传的解析器 id 是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他
字段也将无法绑定)

springmvc跨服务器方式

一、配置web.xml

<servlet>
	<init-param>
		<param-name>readOnly</param-name>
		<param-value>false</param-value>
	</init-param>
	加入此行的含义是:接收文件的目标服务器可以支持写入操作。
</servlet>

二、拷贝jar包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mQZsQvGp-1592493397359)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20191206200345025.png)]

三、编写控制器

@Controller("fileUploadController2")
public class FileUploadController2 {
public static final String FILESERVERURL = 
"http://localhost:9090/day06_spring_image/uploads/";
/**
* 文件上传,保存文件到不同服务器
*/
@RequestMapping("/fileUpload2")
public String testResponseJson(String picname,MultipartFile uploadFile) throws
Exception{
//定义文件名
String fileName = "";
//1.获取原始文件名
String uploadFileName = uploadFile.getOriginalFilename();
//2.截取文件扩展名
String extendName = 
uploadFileName.substring(uploadFileName.lastIndexOf(".")+1, 
uploadFileName.length());
//3.把文件加上随机数,防止文件重复
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
//4.判断是否输入了文件名
if(!StringUtils.isEmpty(picname)) {
fileName = uuid+"_"+picname+"."+extendName; }else {
fileName = uuid+"_"+uploadFileName; }
System.out.println(fileName);
//5.创建 sun 公司提供的 jersey 包中的 Client 对象
Client client = Client.create();
//6.指定上传文件的地址,该地址是 web 路径
WebResource resource = client.resource(FILESERVERURL+fileName);
//7.实现上传
String result = resource.put(String.class,uploadFile.getBytes());
System.out.println(result);
return "success"; } }

四、编写jsp页面,配置文件上传解析器

8.异常处理器

其他层的异常都直接抛出,mvc通过异常处理器拦截异常进行处理,需要自定义异常类继承HandlerExceptionResolver,并且完成配置

自定义

public class CustomExceptionResolver implements HandlerExceptionResolver {
    
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
    
    ex.printStackTrace();
    CustomException customException = null;
    //如果抛出的是系统自定义异常则直接转换
    if(ex instanceof CustomException){
    customException = (CustomException)ex; }else{
    //如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
    customException = new CustomException("系统错误,请与系统管理 员联系!");
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", customException.getMessage());
modelAndView.setViewName("error");
return modelAndView; } }

配置异常处理器

<!-- 配置自定义异常处理器 --> 
<bean id="handlerExceptionResolver"
class="com.itheima.exception.CustomExceptionResolver"/>

9.拦截器

是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的。

我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口。

实现接口

public class HandlerInterceptorDemo1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse 
response, Object handler)
throws Exception {
System.out.println("preHandle 拦截器拦截了");
return true; }
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, 
Object handler,ModelAndView modelAndView) throws Exception {
System.out.println("postHandle 方法执行了");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse 
response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion 方法执行了");
} }

配置拦截器

<!-- 配置拦截器 --> 
<mvc:interceptors> 
<mvc:interceptor> 
<mvc:mapping path="/**"/>
<bean id="handlerInterceptorDemo1"
class="com.itheima.web.interceptor.HandlerInterceptorDemo1"></bean>
</mvc:interceptor>
</mvc:interceptors>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值