SpringMVC笔记

SpringMVC笔记

一、SpringMVC环境搭建及简单应用

1.springMVC.xml配置文件 选中常用的命名空间:beans aop context mvc。
2.通过以下配置,拦截所有请求交给SpringMVC处理。

 <servlet>
  <servlet-name>springDispatcherServlet</servlet-name>
  <!-- spring入口 -->
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <!-- 如果不指定配置文件路径的话,可以把springmvc配置文件放在WEB-INF中,固定名称为    
    springDispatcherServlet-servlet.xml -->
  <param-name>contextConfigLocation</param-name>
  <param-value>classPath:springMVCProject.xml</param-value>
  </init-param>
  <!-- 项目启动自动生效 -->
  <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
  <servlet-name>springDispatcherServlet</servlet-name>
  <!-- 如果项目通过SpringMVC和Servlet同时管理,可以靠拦截器控制,这种说明只有以.action结尾的springmvc处理。
  <url-pattern>.action</url-pattern>
  -->
  <url-pattern>/</url-pattern>
  </servlet-mapping>

3.在代码中可以指定用什么方式提交,默认提交是用get方式,下面可以改成用post方式提交。

@RequestMapping(value = "welcome", method = RequestMethod.POST)

4.前台传入到后端的数据,后端可以这样来接收:
其中value=前端name,required=false代表前台可以什么都不传递,defaultValue如果前台没有传递值过来,默认把里面的值放到id中。

@RequestMapping(value = "getPost" ,method = RequestMethod.POST)
	public String getPost(@RequestParam(value="uname",required =false,defaultValue="123") Integer id){
		System.out.println(id);
		return "success";
	}

5.前端将多个字段传到后端,后端用bean来接收,只需要前端和bean中定义的变量名一致即可获取到:
前端:

<form action="handler/testObject" name="student">
		<input name="id" type="text"> <input name="name" type="text">
		<input name="address.homeAddress" type="text"> 
		<input name="address.schoolAddress" type="text"> 
		<input type="submit" name="提交">
	</form>

后端SpringMVC方式:

@RequestMapping(value = "testObject")
	public String testObject(Student student) {
		return "success";
	}

后端servlet方式:

@RequestMapping(value = "testServletAPI")
	public String testServletAPI(HttpServletRequest request) {
		System.out.println(request.getParameter("name"));
		return "success";
	}

实体类(省略get、set方法):

public class Student {
    private int id;
	private String name;
	private Address address;
	}
	
public class Address {
	private String homeAddress;
	private String schoolAddress;
	}

6.四种页面跳转传递参数方法:
①用ModelAndView方式:

@RequestMapping(value = "testModelAndView")
	public ModelAndView testModelAndView(Student student) {//既有数据又有视图
		ModelAndView modelAndView = new ModelAndView("success");
		modelAndView.addObject("student", student);//相当于request.setAttribute()
		return modelAndView;
	}

②用ModelMap方式:

@RequestMapping(value = "testModelMap")
	public String testModelMap(ModelMap mm) {
		Student student = new Student();
		student.setId(123);
		student.setName("gg");
		mm.addAttribute("student", student);
		return "success";
	}

③用Model方式

@RequestMapping(value = "testModel")
	public String testModel(Model m) {
		Student student = new Student();
		student.setId(123);
		student.setName("gg");
		m.addAttribute("student", student);
		return "success";
	}

④用Map方式

@RequestMapping(value = "testMap")
	public String testMap(Map<String,Object> m) {
		Student student = new Student();
		student.setId(123);
		student.setName("gg");
		m.put("Student", student);
		return "success";
	}

7.如果要在request中存放指定bean,在类头加@SessionAttributes注解。如:

@SessionAttributes("student")
public class SpringMVCHandler {}

8.如果要在request中按照类型存放bean,在类头加@SessionAttributes注解。如:

@SessionAttributes(types = {Student.class,Address.class})
public class SpringMVCHandler {}

9.@ModelAttribute注解修饰的方法会在任何一次请求前被调用,慎重使用。它里面的bean名称可以进行重定义,在其他方法调用到该bean的时候需要用(@ModelAttribute(“stu)Student student)指向。

二、视图解析器

1.简单介绍
视图的顶级接口:View
视图解析器:ViewResolver
2.常见的视图和解析器:InternalResourceViewResolver(在spring.xml文件中,参数有prefix、suffix。
作用是将字符串转换成以字符串名字命名的jsp页面)
public class JstlView extends InternalResourceView {}(源码)
springMVC解析jsp时,默认会使用InternalResourceView ,如果发现jsp中包含了jstl语言,会自动转换
为JstlView子类。
JstlView可以解析jstl、实现国际化操作。
3.国际化:针对不同地区、国家,进行不同的显示。
具体实现国际化的步骤:
①创建资源文件:基名_语言_地区.properties、基名_语言.properties(如果properties中不自动转换成ascii码,可以到jdk安装目录bin中用cmd执行native2ascii.exe文件,可转换ascii,再粘贴到资源文件中)
②配置springmvc.xml,加载资源文件。

<!-- 加载国际化资源文件 i18n是对应国际化资源文件名,以i18n开头的被加载进来-->
<!-- 1.将ResourceBundleMessageSource在程序加载时,加入springmvc:springmvc会自动查找
     id="MessageSource"bean,如果有自动加载(就是id)
     2.如果配置了ResourceBundleMessageSource,则该类会在程序响应人介入-->
	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
	<property name="basename" value="i18n"></property>
	</bean>

③通过jstl使用国际化,需要jar包jstl.jar、standar.jar。需要在jsp上引用

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

4.<mvc:view-controller …>注解
通过springmvc.xml中配置如下标签,可越过controller直接调用其他页面,如:
(注:这个配置会让所有请求转入mvc:中匹配地址,忽略掉@RequestMapping())

<!-- view-name依然可以加上前缀和后缀-->
<mvc:view-controller path="handler/testMvcViewController" view-name="success"/>

如果需要配置和controller共存,需要加入如下注解:(建议配置文件提前加入,很多功能会用到)

<!-- 此配置是springmvc的基础配置,很多功能都需要该配置协调 -->
	<mvc:annotation-driven></mvc:annotation-driven>

5.指定请求方式
地址栏输入controller地址跳到对应映射页面但地址栏不变的模式叫“请求转发模式”,地址栏改变“重定向模式”,如果想改变跳转方式可在return添加关键字如:
(注:此方式springmvc.xml中的前缀和后缀设置会失效)

//forward:请求转发    
return "forward:/view/success.jsp";
//redirect:重定向        
return "redirect:/view/success.jsp";

6.处理静态资源:html、css、js、图片、视频
在springmvc中,如果直接访问静态资源:404。原因:将所有的请求通过通配符“/”拦截,交给springMVC的入口DispatcherServlet去处理:找该请求对应的@RequestMapping,直接在地址栏访问的话就等同于@RequestMapping(“img.jpg”)。
解决静态方案:如果有springMVC对应的@RequestMapping则讲给spring处理,如果没有对应的@RequestMapping,则交给服务器tomcat默认的servlet处理。实现方法只需要增加一个配置(springmvc.xml : <mvc:default-servlet-handler />)
注:这个注解也必须加上:<mvc:annotation-driven ></mvc:annotation-driven>
7.类型转换
①springmvc内置一些常用的类型转换器。
②也可以自定义类型转换:

编写自定义类型转换器的类(实现一个Converter接口)

public class MyConverter implements Converter<String, Student>{
	@Override
	public Student convert(String source) {
		//接收前端传来的字符串
		String[] studentStrArr = source.split("-");
		Student student = new Student();
		student.setId(Integer.parseInt(studentStrArr[0]));
		student.setName(studentStrArr[1]);
		return null;
	}
}

配置:将MyConverter加入到springmvc中:

<!-- 1.将自定义转换器纳入springmvcioc容器 -->
	<bean id="myConverter" class="org.lanqiao.converter.MyConverter"></bean>
	<!-- 2.将myConverter纳入springmvc提供的转化器bean中 -->
	<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
	<property name="converters">
	<set>
	<ref bean="myConverter"/>
	</set>
	</property>
	</bean>
	<!-- 3.将conversionService注册到annotation-driven中 -->
	<!-- 此配置是springmvc的基础配置,很多功能都需要该配置协调 -->
	<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

测试方法:
前端text输入一个字符串:123-456转换后分别放入student

@RequestMapping(value = "testConverter")
	public String testConverter(@RequestParam("studentInfo") Student stu) {
		System.out.println(stu.getId()+","+stu.getName());
		return "success";
	}

三、数据格式化

1.实现步骤:
①配置:(该bean既可以实现格式化,又可以实现类型转换)

<!-- 配置数据格式化依赖的bean -->
	<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"></bean>

②通过注解使用:

@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date birthday;
@NumberFormat(pattern="###.#")//传入的值如:123.4
	private int id;	

四、错误处理、数据校验

1.错误消息:
需要验证的数据,springmvc要求,如果校验失败,将错误信息自动放入该对象后面挨着的BindingResult内,因此顺序不能变。如果要将控制台中的错误消息,可以将错误对象放入request域中,然后在jsp中从requestScope中取。

@RequestMapping(value = "testDateTimeFormat")//如果Student格式化出错,会将错误信息传入result中
	public String testDateTimeFormat(Student stu,BindingResult result,Map<String,Object> map) {
		System.out.println(stu.getId()+","+stu.getName()+","+stu.getBirthday());
		if(result.getErrorCount()>0){
			for(FieldError error :result.getFieldErrors()){
				 System.out.println(error.getDefaultMessage());
				 map.put("errors", result.getFieldErrors());
			}
		}
		return "success";
	}

jsp获取代码如下:

<c:forEach items="${requestScope.errors}" var="error">
${error.getDefaultMessage()}</br>
</c:forEach>

2.数据校验:
JSR303格式校验,如下:

Constraint详细信息
@Null被注释的元素必须为 null
@NotNull被注释的元素必须不为 null
@AssertTrue被注释的元素必须为 true
@AssertFalse被注释的元素必须为 false
@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min)被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past被注释的元素必须是一个过去的日期
@Future被注释的元素必须是一个将来的日期
@Pattern(value)被注释的元素必须符合指定的正则表达式

Hibernate Validator是JSR303的扩展,如下:

Constraint详细信息
@Email被注释的元素必须是电子邮箱地址
@Length被注释的字符串的大小必须在指定的范围内
@NotEmpty被注释的字符串的必须非空
@Range被注释的元素必须在合适的范围内

①依赖的jar:
hibernate-validator.jar
classmate.jar
jboss-logging.jar
validatetion-api.jar
hibernate-validator-annotation-processor.jar
②配置:
此时:要实现Hibernate Validator/JSR303校验,必须实现springmvc提供的接口:ValidatorFactory
LocalValidatorFactoryBean是ValidatorFactory的一个实现类。
<mvc:annotation-driven ></mvc:annotation-driven>在springmvc容器中自动加载一个LocalValidatorFactoryBean类,可以直接实现数据校验。

	<mvc:annotation-driven></mvc:annotation-driven>

③直接使用注解

五、Ajax请求SpringMVC,返回JSON格式数据

1.需要jar包:
添加包时,版本号尽量保持一致或相近。
jackson-annotation.jar
jackson-core.jar
jacksion-databin.jar

2.@ResponseBody
@ResponseBody:告诉springmvc,此时返回不是一个view页面,而是一个ajax调用的返回值。
客户端:

<script type="text/javascript" src="js/jquery.js"></script> 
<script type="text/javascript">
$(document).ready(function(){
	$("#testJson").click(function(){
		//通过ajax请求springmvc
		$.psot("handler/testJson",//服务器地址
		/* {"name":"zs"}, */
		function(result){//服务端处理完毕后的回调函数
			for(var i = 0;i<result.length;i++){
				alert(result[i].id);
				alert(result[i].name);
				alert(result[i].age);
			}
		}
		);
	});
});
</script>

服务端:

@ResponseBody//告诉springmvc,此时返回不是一个view页面,而是一个ajax调用的返回值
	@RequestMapping(value = "testJson")
	public List<Student> testJson() {
		Student stu1 = new Student(1, "zs", 21);
		Student stu2 = new Student(2, "ls", 22);
		Student stu3 = new Student(3, "ws", 23);
		List<Student> students = new ArrayList<>();
		students.add(stu1);
		students.add(stu2);
		students.add(stu3);
		return students;
	}

六、SpirngMVC实现文件上传

1.springmvc和Servlet方式的本质一样,都是通过两个组件来实现。
Springmvc可以简化文件上传的代码,必须满足条件:实现MultipartResolver接口,该接口的实现类SpringMVC也已经提供CommonsMultipartResolver。
具体步骤:(直接使用CommonsMultipartResolver实现上传)
①jar包:commons-fileupload.jar、commons-io.jar
②配置:CommonsMultipartResolver
将其加入SpringIOC.xml容器

<!-- 配置:CommonsMultipartResolver,将其加入SpringIOC.xml容器    
	实现文件上传 id值是固定的 “multipartResolver” springioc初始化时,会自动寻找改名的bean,并加入ioc容器-->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<property name="defaultEncoding" value="UTF-8"></property>
	<!-- 上传单位文件最大值 单位是B-->
	<property name="maxInMemorySize" value="10240000"></property>
	</bean>

③处理的方法:
客户端:

<form action="handler/testUpload" method="post" enctype="multipart/form-data">
		<input type="file" name ="file">
		描述:<input name="desc" type="text"> 
		<input type="submit" value="上传">
	</form>

服务端:

@RequestMapping(value = "testUpload")
	public String testUpload(@RequestParam("desc") String desc,@RequestParam("file")MultipartFile file) throws IOException  {
		System.out.println(desc);
		//输入流
		InputStream inputStream = file.getInputStream();
		//输出流
		OutputStream fileOutputStream = new FileOutputStream("d:\\"+file.getOriginalFilename());
		//字节循环写入
		byte[] bs = new byte[1024];
		int len = -1;
		while((len = inputStream.read(bs)) != -1){
			fileOutputStream.write(bs,0,len);
		}
		inputStream.close();
		fileOutputStream.close();
		return "success";
	}

2.拦截器:
Springmvc:要想实现拦截器,必须实现一个接口HandlerInterceptor,接口中有三个方法:
preHandle:拦截请求
postHandle:拦截相应
afterCompletion:当页面被渲染完毕后出发

①编写拦截器:拦截器类实现HandlerInterceptor接口。
②配置:将写好的拦截器配置到springmvc中。

七、异常处理

**1.Springmvc:**HandlerExceptionResolver接口
这个接口的每一个实现类,都是异常的一种处理方式。
ExceptionHandlerExecptionResolver:主要提供了@ExceptionHandler注解, 通过注解处理异常。
注:@ExceptionHandler标识的方法参数,必须是异常类型的Throwable或子类,不能包含其他参数。

// 该方法可以捕获本类中,抛出的ArithmeticException异常ArrayIndexOutOfBoundsException
	@ExceptionHandler({ ArithmeticException.class,ArrayIndexOutOfBoundsException.class })
	public ModelAndView handlerArithmeticException(Exception e) {
		System.out.println(e+"===============");
		ModelAndView mv = new ModelAndView("error");
		mv.addObject("e",e);
		return mv;
	}
	@RequestMapping("testExceptionHandler2")
	public String testExceptionHandler2() {
		int[] nums = new int[2];
		System.out.println(nums[2]);
		return "success";
	}

异常处理的优先级,路径最短优先
如果一个方法抛出一个ArithmeticException异常,该类中有两个异常处理方法:
会优先选择handlerArithmeticException1方法来处理。

@ExceptionHandler({ ArithmeticException.class})
	public ModelAndView handlerArithmeticException1(Exception e) {
	@ExceptionHandler({ ArithmeticException.class })
	public ModelAndView handlerArithmeticException2(ArithmeticException) {

总结:如果一个方法用于处理异常,并且只处理当前类的异常:方法前加@ExceptionHandler
如果一个方法用于处理异常,并且处理所有类的异常:类前加@ControllerAdvice、方法前加@ExceptionHandler。
2.ResponseStatusExceptionResolver,自定义异常显示页面

//调用端
@RequestMapping("testMyException")
	public String testMyException(@RequestParam("i") Integer i) throws MyArrayIndexOutofBoundsException {
		if(i == 3){
			throw new MyArrayIndexOutofBoundsException();
		}
		int[] nums = new int[2];
		System.out.println(nums[2]);
		return "success";
	}

@ResponseStatus(value = HttpStatus.FORBIDDEN,reason="数组越界!")
public class MyArrayIndexOutofBoundsException extends Exception{//自定义异常
}

八、SSM整合

Spring—SpringMVC—Mybatis
Spring-----Mybatis:需要整合:将Mybatis的SqlSessionFactory交给Spring。
Spring-----SpringMVC:就是将两个框架各自配置一遍。
1.SM整合步骤:
①引入jar:
mybatis-spring.jar spring-tx.jar spring-jdbc.jar spring-expression.jar spring-context-supoprt.jar
spring-core.jar spring-context.jar spring-beans.jar spring-aop.jar spring-web.jar
commons-logging.jar commons-dbcp.jar ojdbc.jar mybatis.jar log4j.jar commons-pool.jar
2.类—表
Student-----student
3.spring配置文件applicationContext.xml
(与spring整合时,Mybati配置文件conf.xml可以省略)

九、表单标签

1.表单标签:
自定义标签:el/jstl
Spring EL:支持各种类型的请求方式(查询doGet、增加doPost、删除doDelet、修改doPut)
可以将对象和表单绑定 对象的属性----表单里的path值一一对应。
使用Idea配置SpringMVC项目:
新建项目选择Spring>SpringMVC创建自动下载相关的jar
处理jar:Project Structure>Arifacts>fix:miss all…
开发代码:
①页面引入标签库:<%@taglib prefix=“form” uri=“http://www.springframework.org/tags/form” %>
使用form时,springmvc标签默认自动从“command”的对象中获取值,如果后端用的事map.put()名字不是command,需要手工指定:command=“cd” 和 modelAttribute=“cd” 二选一定义即可。

 public String testForm(Map<String,Person> map){
        Person person = new Person();
        person.setName("zs");
        map.put("cd",person);
        return "index";
    }

2.支持各种表单提交方式:
①编写method=“put|delete”
②过滤器:为了让浏览器支持put|delete等请求,需要web.xml配置过滤器HiddenHttpMethodFilter。

<!-- 用于支持delete put等请求-->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

HiddenHttpMethodFilter会将全部请求中name=“_method”的隐藏域 进行put|delete处理。

十、checkbox:自动绑定request域中的值

前端有复选框可初始化勾选数量,动态获取复选框数量。
后端:

@RequestMapping("/testForm")
    public String testForm(Map<String,Object> map){
        Person person = new Person();
        person.setSix(true);
        List<String> hobbies = new ArrayList<>();
        hobbies.add("football");
        hobbies.add("basketball");
        person.setHobbies(hobbies);
        Map<String,String> allHobbies = new HashMap<>();
        allHobbies.put("football","足球");
        allHobbies.put("basketball","篮球");
        allHobbies.put("pingpang","乒乓球");
        allHobbies.put("yumao","羽毛球");
        map.put("command",person);
        map.put("allHobbies",allHobbies);
        return "index";
    }

前端:

<form:form action="testForm">
	<%--复选框--%>
    <form:checkboxes path="hobbies" items="${allHobbies}"/>
    <%--单选框--%>
    <form:radiobuttons path="favirateBall" items="${allHobbies}"/>
    <%--下拉框1--%>
    <form:select path="favirateBall" items="${allHobbies}"/>
    <%--下拉框2--%>
    <form:select path="favirateBall" ">
    <form:option value="football">足球</form:option>
    <form:option value="basketball">篮球</form:option>
    <form:option value="pingpang">乒乓</form:option>
	</form:select>
	 <%--下拉框3--%>
	<form:select path="favirateBall" >
        <form:options items="${allHobbies}"/>
    </form:select>

注:下拉框优先级:方式2、3同时存在,优先使用方式2
方式1、2同时存在,优先使用方式1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值