初学springmvc

看完ssm的视频,也写了一些小dome,觉得配置真的麻烦,因为没有做相关的项目,所以我没有体验到ssm的便利,我觉得动态反射,依赖注入好厉害

第一个SpringMVC入门程序

1:使用框架第一步,导入相应的jar包

报错NoClassDefFoundError:缺少jar

2第二步配置相关的xml文件

在web.xml中

<!-- 配置 spring mvc 的核心控制器 -->
<servlet> <servlet-name>SpringMVCDispatcherServlet</servlet-name> <servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 配置初始化参数,用于读取 SpringMVC 的配置文件 -->
 <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMVC.xml</param-value>
</init-param>
<!-- 配置 servlet 的对象的创建时间点:应用加载时创建。
取值只能是非 0 正整数,表示启动顺序 -->
 <load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping> <servlet-name>SpringMVCDispatcherServlet</servlet-name> <url-pattern>/</url-pattern>
</servlet-mapping>

在src下创建:SpringMVC.xml(下面的属性一般都要有)

<!-- 扫描 有注解的包 -->
 <context:component-scan base-package="cn.sunshine.controller"></context:component-scan>
 
 <!-- 配置视图解析器 -->
bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 <property name="prefix" value="/pages/"></property>
 <property name="suffix" value=".jsp"></property>
 </bean>
 <!--此配置是SpringMVC的基础配置,很功能都需要通过该注解来协调  -->
 <mvc:annotation-driven></mvc:annotation-driven>

在src下创建cn.sunshine.controller包
在其中创建相应的springmvc的java文件

一定要有@Controller,@RequestMapping注解

一个例子

@Controller
@RequestMapping(value="handler") //映射
public class SpringMVCHandler {
		@RequestMapping(value="welcome",method=RequestMethod.POST,params= {"name=zs","age!=23","!height"})//映射
		public String  welcome() {
			return "success" ;//  views/success.jsp,默认使用了 请求转发的 跳转方式
		}
		}

映射是 去匹配@RequestMapping注解,可以和方法名、类名不一致

重要的注解

@Controller
注解作用:
注册Bean到Spring上下文,Bean的默认ID为类名称首字母小写,也可以自己指定。

@RequestMapping
注解作用:
用来定义访问的url。

@RequestParam作用:

将请求参数绑定到你控制器的方法参数上

@PathVariable获取动态参数

@Autowired
注解作用:

可以对成员变量、方法和构造函数进行标注,来完成自动装配工作。可以消除get,set方法。

ant风格的请求路径

?  单字符
*  任意个字符(0或多个)
** 任意目录

用过滤器实现delelte|put请求

REST风格 :软件编程风格
Springmvc:
GET :查
POST :增
DELETE :删
PUT :改

普通浏览器 只支持get post方式 ;其他请求方式 如 delelte|put请求是通过 过滤器新加入的支持。

springmvc实现 :put|post请求方式的步骤
a.增加在web.xml过滤器

<!-- 增加HiddenHttpMethodFilte过滤器:目的是给普通浏览器 增加 put|delete请求方式 -->
	<filter>
			<filter-name>HiddenHttpMethodFilte</filter-name>
			<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
	
	</filter>
	
	<filter-mapping>
			<filter-name>HiddenHttpMethodFilte</filter-name>
			<url-pattern>/*</url-pattern>
	</filter-mapping>

b.表单

<form action="handler/testRest/1234" method="post">
	<input type="hidden"  name="_method" value="DELETE"/>
	<input type="submit" value="删">
</form>

i:必须是post方式
ii:通过隐藏域 的value值 设置实际的请求方式 DELETE|PUT

c.控制器
@RequestMapping(value=“testRest/{id}”,method=RequestMethod.DELETE)
public String testDelete(@PathVariable(“id”) Integer id) {
System.out.println("delete:删 " +id);
//Service层实现 真正的增
return “success” ;// views/success.jsp,默认使用了 请求转发的 跳转方式
}
通过 method=RequestMethod.DELETE 匹配具体的请求方式

此外,可以发现 ,当映射名相同时@RequestMapping(value="testRest),可以通过method处理不同的请求。

处理模型数据

如果跳转时需要带数据:V、M,则可以使用以下方式:
ModelAndView、ModelMap 、Map、Model -数据放在了request作用域

示例:
public String testModel(Model model| Map<String,Object> m) {

m.put(x,"…"); 就会将x对象 放入request域中

如何将上述数据放入session中?@SessionAttributes(…)

@ModelAttribute
i.经常在 更新时使用
ii.在不改变原有代码的基础之上,插入一个新方法。

通过@ModelAttribute修饰的方法 ,会在每次请求前先执行;
并且该方法的参数map.put()可以将 对象 放入 即将查询的参数中;
必须满足的约定:
map.put(k,v) 其中的k 必须是即将查询的方法参数 的首字母小写
如果不一致,需要通过@ModelAttribute声明。

@ModelAttribute会在 该类的每个方法执行前 均被执行一次(基于一种思想:一个控制器 只做一个功能),因此使用时需要注意。

视图、视图解析器

视图的顶级接口:View
视图解析器:ViewResolver

常见的视图和解析器:
InternalResourceView、InternalResourceViewResolver

public class JstlView extends InternalResourceView:

springMVC解析jsp时 会默认使用InternalResourceView,
如果发现Jsp中包含了jstl语言相关的内容,则自动转为JstlView。

JstlView 可以解析jstl\实现国际化操作

国际化: 针对不同地区、不同国家 ,进行不同的显示

中国:(大陆、香港) 欢迎
美国: welcome

i18n_zh_CH.properties
resource.welcome=你好
resource.exist=退出

i18n.properties

具体实现国际化步骤:
a.创建资源文件
基名_语言_地区.properties
基名_语言.properties

b.配置springmvc.xml,加载资源文件

<!-- 加载国际化资源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property>
</bean>

ResourceBundleMessageSource会在springmvc响应程序时 介入(解析国际化资源文件)

c.通过jstl使用国际化
jstl.jar standar.jar

springmvc在启动时,会自动查找一个id="messageSource"的bean,如果有 则自动加载

InternalResourceViewResolver其他功能:
1.<mvc:view-controller …>
index.jsp -> Controller(@RequsetMapping(“a”)) ->succes.jsp

要用SpringMVC实现:index.jsp -> succes.jsp :
<mvc:view-controller path=“a” view-name=“success” />

以上注解 ,会让所有的请求 转入mvc:..中匹配映射地址,而会忽略调@RequsetMapping();
如果想让 @RequsetMapping(“a”) 和mvc:..共存,则需要加入一个注解:mvc:annotation-driven</mvc:annotation-driven>

2.指定请求方式

指定跳转方式:return “forward:/views/success.jsp”;

forward: redirect: ,需要注意 此种方式,不会被视图解析器加上前缀(/views)、后缀(.jsp)

3.处理静态资源:html css js 图片 视频

可以与用户交互、因为时间/地点的不同 而结果不同的内容:动态(百度:天气 )

在SpringMVC中,如果直接访问静态资源:404 。原因:之前将所有的请求 通过通配符“、” 拦截,进而交给 SPringMVC的入口DispatcherServlet去处理:找该请求映射对应的 @requestMapping

http://localhost:8888/SpringMVCProject/img.png

@RequsetMapping(“img.png”)
return sucess

解决:如果是 需要mvc处理的,则交给@RequsetMapping(“img.png”)处理;如果不需要springmvc处理,则使用 tomcat默认的Servlet去处理。
tomcat默认的Servlet去处理:如果有 对应的请求拦截,则交给相应的Servlet去处理;如果没有对应的servlet,则直接访问。
tomcat默认的Servlet在哪里?在tomcat配置文件\conf\web.xml中

<servlet>
	<servlet-name>abc</servlet-name>
	<servlet-class>xxx.xxx.xx.ABCServlet</servlet-class>
</servlet>

<servlet-mapping>
	<servlet-name>abc</servlet-name>
	<url-pattern>/abc</url-pattern>
</servlet-mapping>

解决静态资源方案:如果有springmvc对应的@requestMapping则交给spring处理;如果没有对应@requestMapping,则交给服务器tomcat默认的servlet去处理 :实现方法,只需要增加2个注解即可 springmvc.xml:

<mvc:default-servlet-handler></mvc:default-servlet-handler>
<mvc:annotation-driven></mvc:annotation-driven>

4.类型转换

a.Spring自带一些 常见的类型转换器:
public String testDelete(@PathVariable(“id”) String id) ,即可以接受int类型数据id 也可以接受String类型的id

b.可以自定义类型转换器
i.编写 自定义类型转器的类 (实现Converter接口)

public class MyConverter  implements Converter<String,Student>{

@Override
	public Student convert(String source) {//source:2-zs-23
		//source接受前端传来的String:2-zs-23
		String[] studentStrArr = source.split("-") ;
		Student student = new Student();
		student.setId(  Integer.parseInt(  studentStrArr[0]) );
		student.setName(studentStrArr[1]);
		student.setAge(Integer.parseInt(studentStrArr[2] ));
		return student;
	}

}

ii.配置:将MyConverter加入到springmvc中

<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>

测试转换器:

	@RequestMapping(value="testConverter")
		public String testConverter(@RequestParam("studentInfo")  Student student) {// 前端:2-zs-23  
			
System.out.println(student.getId()+","+student.getName()+","+student.getAge());
				return "success";
		}

其中@RequestParam(“studentInfo”)是触发转换器的桥梁:
@RequestParam(“studentInfo”)接受的数据 是前端传递过来的:2-zs-23 ,但是 需要将该数据 复制给 修饰的目的对象Student;因此SPringMVC可以发现 接收的数据 和目标数据不一致,并且 这两种数据分别是 String、Student,正好符合public Student convert(String source)转换器。

5.数据格式化

SimpleDateForamt sdf = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);
SPringMVC提供了很多注解,方便我们数据格式化
实现步骤:
a.配置

	<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
	</bean>在这里插入代码片

b.通过注解使用
@DateTimeFormat(pattern=“yyyy-MM-dd”)
@NumberFormat(parttern="###,#")

1.错误消息:
public String testDateTimeFormat(Student student, BindingResult result ,Map<String,Object> map) {
需要验证的数据是 Student中的birthday, SPringMVC要求 如果校验失败 则将错误信息 自动放入 该对象之后紧挨着的 BindingResult中。
即Student student, BindingResult result之间 不能有其他参数。

如果要将控制台的错误消息 传到jsp中显示,则可以将 错误消息对象放入request域中,然后 在jsp中 从request中获取。

2. 数据校验

JSR303
Hibernate Validator

使用Hibernate Validator步骤:

a.jar(注意各个jar之间可能存在版本不兼容)
hibernate-validator-5.0.0.CR2.jar classmate-0.8.0.jar jboss-logging-3.1.1.GA.jar
validation-api-1.1.0.CR1.jar hibernate-validator-annotation-processor-5.0.0.CR2.jar

b配置
<mvc:annotation-driven ></mvc:annotation-driven>
此时mvc:annotation-driven的作用:要实现Hibernate Validator/JSR303 校验(或者其他各种校验),必须实现SpringMVC提供的一个接口:ValidatorFactory

LocalValidatorFactoryBean是ValidatorFactory的一个实现类。
<mvc:annotation-driven ></mvc:annotation-driven>会在springmvc容器中 自动加载一个LocalValidatorFactoryBean类,因此可以直接实现数据校验。

c.直接使用注解
public class Student {

public class Student {
@Past//当前时间以前
private Date birthday ;
}

在校验的Controller中 ,给校验的对象前增加 @Valid
public String testDateTimeFormat(@Valid Student student, BindingResult result ,Map<String,Object> map) {
{…}

Ajax请求SpringMVC,并且JSON格式的数据

a.jar
jackson-annotations-2.8.9.jar
jackson-core-2.8.9.jar
jackson-databind-2.8.9.jar

b。
@ResponseBody修饰的方法,会将该方法的返回值 以一个json数组的形式返回给前台

        @ResponseBody//告诉SpringMVC,此时的返回 不是一个 View页面,而是一个 ajax调用的返回值(Json数组)
		@RequestMapping(value="testJson")
		public List<Student> testJson() {
			//Controller-Service-dao
			//StudentService studentService = new StudentServiceImp();
//			List<Student> students =  studentService.qeuryAllStudent();
			//模拟调用service的查询操作
			
			...
			List<Student> students = new ArrayList<>();
			students.add(stu1) ;
			students.add(stu2) ;
			students.add(stu3) ;
			
			return students;
		}


前台:服务端将返回值结果 以json数组的形式 传给了result。

$("#testJson").click(function(){
					//通过ajax请求springmvc
					$.post(
						"handler/testJson",//服务器地址
						//{"name":"zs","age":23}
						function(result){//服务端处理完毕后的回调函数 List<Student> students, 加上@ResponseBody后, students实质是一个json数组的格式
							for(var i=0;i<result.length ;i++){
								alert(result[i].id +"-"+result[i].name +"-"+result[i].age);
							}
						}
					);

1.SpringMVC实现文件上传:

和Servlet方式的本质一样,都是通过commons-fileupload.jar和commons-io.jar
SpringMVC可以简化文件上传的代码,但是必须满足条件:实现MultipartResolver接口 ;而该接口的实现类SpringMVC也已经提供了CommonsMultipartResolver

具体步骤:(直接使用CommonsMultipartResolver实现上传)
a.jar包
commons-fileupload.jar、commons-io.jar
b.配置CommonsMultipartResolver
将其加入SpringIOC容器

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 上传单个文件的最大值,单位Byte;如果-1,表示无限制 -->
		<property name="maxUploadSize"  value="102400"></property>
</bean>
c.处理方法
		//文件上传处理方法
		@RequestMapping(value="testUpload") //abc.png
		public String testUpload(@RequestParam("desc") String desc  , @RequestParam("file") MultipartFile file  ) throws IOException {
			
			System.out.println("文件描述信息:"+desc);
			//jsp中上传的文件:file
			
			InputStream input = file.getInputStream() ;//IO
			String fileName = file.getOriginalFilename() ;
			
			OutputStream out = new FileOutputStream("d:\\"+fileName) ;
			
			
			byte[] bs = new byte[1024];
			int len = -1;
			while(( len = input.read(bs)) !=-1 ) {
				out.write(bs, 0, len);
			}
			out.close();
			input.close();
			//将file上传到服务器中的 某一个硬盘文件中
		System.out.println("上传成功!");
			
			return "success";
		}

<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>

框架: 将原来自己写的1000行代码,变成:框架帮你写900行,剩下100行自己写

控制器:handler servlet controller action

2拦截器

拦截器的原理和过滤器相同。
SpringMVC:要想实现拦截器,必须实现一个接口HandlerInterceptor

a.编写拦截器implements HandlerInterceptor
b.配置:将自己写的拦截器 配置到springmvc中(spring)

拦截器1拦截请求- 拦截器2拦截请求 - 请求方法 - 拦截器2处理相应-拦截器1处理相应- 只会被 最后一个拦截器的afterCompletion()拦截

如果有多个拦截器,则每个拦截器的preHandle postHandle 都会在相应时机各被触发一次;但是afterCompletion, 只会执行最后一个拦截器的该方法。

3.异常处理

SpringMVC: HandlerExceptionResolver接口,

该接口的每个实现类 都是异常的一种处理方式:

a.
ExceptionHandlerExceptionResolver: 主要提供了@ExceptionHandler注解,并通过该注解处理异常

//该方法 可以捕获本类中  抛出的ArithmeticException异常
@ExceptionHandler({ArithmeticException.class,ArrayIndexOutOfBoundsException.class  })
public String handlerArithmeticException(Exception e) {
	System.out.println(e +"============");
	return "error" ;
}

@ExceptionHandler标识的方法的参数 必须在异常类型(Throwable或其子类) ,不能包含其他类型的参数

异常处理路径:最短优先
如果有方法抛出一个ArithmeticException异常,而该类中 有2个对应的异常处理法你发:

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

@ExceptionHandler({ArithmeticException.class })
public ModelAndView handlerArithmeticException1(Exception e) {}
则优先级: 最短优先。

@ExceptionHandler默认只能捕获 当前类中的异常方法。
如果发生异常的方法 和处理异常的方法 不在同一个类中:@ControllerAdvice

总结:如果一个方法用于处理异常,并且只处理当前类中的异常:@ExceptionHandler
如果一个方法用于处理异常,并且处理所有类中的异常: 类前加@ControllerAdvice、 处理异常的方法前加@ExceptionHandler

b.
ResponseStatusExceptionResolver:自定义异常显示页面 @ResponseStatus

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

}

@ResponseStatus也可以标志在方法前:
@RequestMapping(“testMyException”)
public String testMyException(@RequestParam(“i”) Integer i) throws MyArrayIndexOutofBoundsException {
if(i == 3) {
throw new MyArrayIndexOutofBoundsException();//抛出异常
}
return “success” ;
}

@RequestMapping(“testMyException2”)
public String testMyException2(@RequestParam(“i”) Integer i) {
if(i == 3) {
return “redirect:testResponseStatus” ;//跳转到某一个 异常处理方法里
}
return “success” ;
}

SSM整合(没有成功)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值