Java学习笔记——SpringMVC框架

一、注解

@RequestMapping:此注解可以放在方法和类上面,用于用于映射url到控制器类或一个特定的处理程序方法,若用在类上,则此类所有处理请求的方法都以该地址作为父路径。还有各种属性

	/**
	 * @RequestMapping有8个属性
	 * 	value:访问路径,若只有value属性可以省略不写value,例@RequestMapping("/t")
	 * 	method:接受访问的请求方式有GET、POST、PUT、DELETE等。
	 * 	params:是表明处理请求必须的参数
	 * 	headers:表明处理请求的请求头参数
	 * 	consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html
	 * 	produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
	 * 
	 * */
	@RequestMapping(value="/t",method=RequestMethod.GET,params={"name","age!=12"},
		headers={"Accept-Language=en-US,zh;q=0.8"},consumes={"application/json"},produces={})
	public String t(){
		System.out.println(2);
		return "success";
	}

@PathVariable

/**
	 * @PathVariable:SpringMVC向rest风格发展的标志。
	 * */
		@RequestMapping("/t1/{id}")
		public String t1(@PathVariable("id")Integer id){
			System.out.println(id);
			return "success";
		}

   @RequestParam

/**
	 * @RequestParam:获取请求参数
	 * 	required设置非必要参数
	 * 	defaultValue设置默认参数值
	 * 	注意:若required为false时要把int设置成Integer类型或者设置defaultValue值,
	 * 	否则抛出IllegalStateException异常
	 * */
		@RequestMapping("/t2")
		public String t2(@RequestParam("id")Integer id,
				@RequestParam(value="name",required=false/*,defaultValue="0"*/)int name){
			System.out.println(id);
			System.out.println(name);
			return "success";
		}

   @RequestHeader

/**
	 * @RequestHeader:获取请求头参数
	 * */
		@RequestMapping("/t3")
		public String t3(@RequestHeader(value="Accept-Language")String s1){
			System.out.println(s1);		//输出结果为:	zh-CN,zh;q=0.8
			return "success";
		}

   @CookieValue

/**
	 * @CookieValue:获取Cookie各属性值
	 * */
		@RequestMapping("/t4")
		public String t4(@CookieValue("JSESSIONID")String s1){
			System.out.println(s1);		
			return "success";
		}

 

              @SessionAttributes:讲数据放到session域里面

              @ModelAttribute:被此注解标记的方法会在每个目标方法执行之前先被调用一次!(但内部实行原理较复杂,可以参考尚硅谷SpringMVC第20集)

                @ControllerAdvice:修饰处理异常的类。 

                @ResponseStatus:自定义异常类,可以标注类或者方法上。

@ResponseStatus(reason="异常",value=HttpStatus.NOT_FOUND)
public class FirstException extends RuntimeException{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
}
		//@ResponseStatus(reason="异常two",value=HttpStatus.NO_CONTENT)
		@RequestMapping("/t12")
		public String t12(@RequestParam("num")int num){
			System.out.println(1);
			if(num==1){
				System.out.println(2);
				throw new FirstException();
			}
			System.out.println("FirstException");
			return "success";
		}

二、SpringMVC的应用

1、SpringMVC支持pojo入参,若一个表单中各个属性有与之相配的实体类。可以直接将实体类入参,SpringMVC会自动将表单中各个参数封装到实体类中去。例:

2、增删改查对应着post、delete、put、get,因为表单只能提交为post和get,使用hidden隐藏域、name=“_method”,添加HiddenHTTPMethodFilter过滤器把post请求转化为delete或put请求

3、SpringMVC支持原生servletAPI

4、ModelAndView、Map处理模型数据(ModelMap也一样)

/**
	 * Map处理模型数据
	 * */
		@RequestMapping("/t6")
		public String t6(Map<String, Object> map){
			map.put("time", new Date());
			return "success";
		}
/**
	 * ModelAndView处理模型数据
	 * */
		@RequestMapping("/t5")
		public ModelAndView t5(){
			ModelAndView modelAndView=new ModelAndView("success");
			modelAndView.addObject("time", new Date());	
			return modelAndView;
		}

        5、国际化资源

                1、首先要在配置文件中配置ResourceBundleMessageSource类来处理国际化资源文件。

                2、在src目录下创建资源文件

                          

         6、WEB-INF下的文件是不能被直接访问的,但有时候我们也需要直接访问一些页面,例如登录注册页面。这是就可以   用<mvc:view-controller path="/q" view-name="q"/>标签,不过该标签需要和<mvc:annotation-driven></mvc:annotation-driven>标签一起用。 

<!-- 配置直接转发页面 -->
	<!-- 可以直接转发的页面,无需经过Handler的方法 -->
	<mvc:view-controller path="/q" view-name="q"/>
	
	<mvc:annotation-driven></mvc:annotation-driven>

         7、 SpringMVC可以自定义视图,可以整合Excel,jsp等视图技术。只要配置BeanNameViewResolver类,order值越小,优先级越高,InternalResourceViewResolver的order为 Integer.MAX_VALUE。视图类实现View接口。接口return返回值只需写上视图类的首字母小写全称就可以了。

<!-- 第四步:建立jsp试图解析器 -->
	<bean id="jspResourceViewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	
	<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
		<property name="order" value="100"></property>
	</bean>
@Component
public class HelloView implements View {
	@Override
	public String getContentType() {
		return "text/html";
	}
	@Override
	public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		response.getWriter().print("hello"+new Date());
	}
}
		@RequestMapping("/t9")
		public String t9(){
			System.out.println("t9");
			return "helloView";
		}

           8、SpringMVC重定向可以在return "redirect:/namespace/toController";转发:return "forward:/namespace/toController";

           9、SpringMVC类型转换自定义转换类继承org.springframework.core.convert.converter类,并注册为Spring成员。

           配置ConversionServiceFactoryBean,并在<mvc:annotation-driven>的注入属性conversion-service,属性值是ConversionServiceFactoryBean   Bean的id值。

          10、mvc:annotation-driven   标签

      在配置文件中配置<mvc:annotation-driven>会自动注册三个Bean。RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的,并且提供了数据绑定支持。

             11、数据格式化。时间、数字等可以直接在实体类字段上面添加注解,时间用@DateTimeFormat、数字用@NumberFormat,若想自定义类型和SpringMVC提供的类型转换同时生效则要把ConversionServiceFactoryBean换成FormattingConversionServiceFactoryBean。                                         

                  12、数据校验,加入jsr 303数据验证jar包,然后在需要数据验证的bean类字段上加上需要验证的注解。在接口上bean类入参前面要加上@Vaild注解,SpringMVC会自动把错误信息放到BindingResult里面。 

	@Min(100)
	@NumberFormat(pattern="#,###,###.#")
	private Integer id;
	
	@NotEmpty
	private String age;
	
	@NotNull
	private String name;
	
	@DateTimeFormat(pattern="yyyy-mm-dd")
	private Date brith;
	
	@Email
	private String Email;
		@RequestMapping("/t10")
		public String t10(@Valid User user,BindingResult result){
			System.out.println(user);
			if(result.getErrorCount()>0){
				System.out.println("error!");
				
				for(FieldError fieldError:result.getFieldErrors()){
					System.out.println(fieldError.getField()+"---"+fieldError.getDefaultMessage());
				}
			}
			return "success";
		}

                   13、返回json数据,加入三个jar包,然后再接口上加上@ResponseBody注解,返回值直接为数据集合。返回值为byte[]数组可以实现下载的效果。                                                                                  

                   14、SpringMVC文件上传利用 MultipartResolver接口,SpringMVC自身没有提供上传实现,利用Apache的commons-fileupload-1.3.1.jar和commons-io-2.4.jar,表单的file名字和入参的@RequestParam的属性值要一致。 

                   

                   15、SpringMVC拦截器,<mvc:mapping path="/test/*" />可以配置拦截器的作用范围。拦截器的作用顺序跟在配置文件中的配置顺序有关,preHandle方法执行顺序是配置文件中的正序,postHandle和afterCompletion方法的配置文件中的反序。

public class FirstInterceptor implements HandlerInterceptor{
	/**
	 * 		方法在目标方法渲染视图之后执行方法。
	 * */
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("FirstInterceptor   -    "+"afterCompletion");
	}

	/**
	 * 		方法在目标方法之后,渲染视图之前执行。
	 * 		入参属性中有ModelAndView,可以对请求域中的属性或视图做出修改。
	 * */
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("FirstInterceptor   -    "+"postHandle");
	}

	/**
	 * 		方法在目标方法之前执行
	 * 		返回true,后续的拦截器会被继续执行。
	 * 		返回false,后续的拦截器不会被继续执行。
	 * */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		System.out.println("FirstInterceptor   -    "+"preHandle");
		return true;
	}
}
<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="104857600" />
		<property name="maxInMemorySize" value="4096" />
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- <property name="uploadTempDir" value="fileUpload/temp"></property> -->
	</bean>

     若第一个拦截器返回的是true,第二个返回的是false时。

                     16、SpringMVC异常处理

        ①、在当前Handler中添加异常处理方法使用@ExceptionHandler注解修饰,并传入异常类。

        ②、@ExceptionHandler方法中的入参不可以传入Map中。若想把异常传到页面上则需要用到ModelAndView对象。           

        ③、@ExceptionHandler方法标记的异常有优先级的问题,与发生的异常匹配度越高优先级越高。也可以写专门处理异常的类,使用@ControllerAdvice注解来修饰类,若在当前Handler找不到匹配的异常处理(当前Handler中的@ExceptionHandler方法异常类是发生异常的父类,也会找到当前Handler的方法处理异常,即只有当前Handler没有与之匹配的异常类才会去找@ControllerAdvice修饰的类处理异常),则会去被@ControllerAdvice修饰的类中找匹配的异常处理方法来处理异常。

		@ExceptionHandler(ArithmeticException.class)
		public ModelAndView handlerException(Exception ex){
			System.out.println(ex);
			ModelAndView modelAndView=new ModelAndView("error");
			modelAndView.addObject("exception",ex);
			return modelAndView;
		}
	
		@RequestMapping("/t11")
		public String t11(@RequestParam("num")int num){
			int i=10/num;
			System.out.println(i);
			return "success";
		}
@ControllerAdvice
public class ExceptionHandler {
	@org.springframework.web.bind.annotation.ExceptionHandler(ArithmeticException.class)
	public ModelAndView handlerException(Exception ex){
		System.out.println("--->>"+ex);
		ModelAndView modelAndView=new ModelAndView("error");
		modelAndView.addObject("exception",ex);
		return modelAndView;
	}
}

                  17、SpringMVC在restfull风格中无法获取小数点,详细原因参考

         解决方法有两种:

             1.在占位符里添加:.+,

             2.在<mvc:annotation-driven></mvc:annotation-driven>中添加<mvc:path-matching registered-suffixes-only="true"/>

.三、总结 

      1、SpringMVC运行流程。

        一、先用文字描述

        1.用户发送请求到DispatchServlet

        2.DispatchServlet根据请求路径查询具体的Handler

        3.HandlerMapping返回一个HandlerExcutionChain给DispatchServlet

         HandlerExcutionChain:Handler和Interceptor集合

        4.DispatchServlet调用HandlerAdapter适配器

        5.HandlerAdapter调用具体的Handler处理业务

        6.Handler处理结束返回一个具体的ModelAndView给适配器

           ModelAndView:model-->数据模型,view-->视图名称

        7.适配器将ModelAndView给DispatchServlet

        8.DispatchServlet把视图名称给ViewResolver视图解析器

        9.ViewResolver返回一个具体的视图给DispatchServlet

        10.填充数据,渲染视图。

        11.展示给用户

       二、画图解析

         2 、SpringMVC三大组件处理器映射器、处理器适配器、视图解析器。

处理器映射器:注解式处理器映射器,对类中标记了@ResquestMapping的方法进行映射,根据@ResquestMapping定义的url匹配@ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器。

<!-- 配置处理器映射器 -->

<bean

class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />

处理器适配器:对标记@ResquestMapping的方法进行适配

<!-- 配置处理器适配器 -->

<bean

class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />

解决办法:

SpringMVC使用<mvc:annotation-driven>自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter

可以在springmvc.xml配置文件中使用<mvc:annotation-driven>替代注解处理器和适配器的配置。

<!-- 注解驱动 -->

<mvc:annotation-driven />

 

视图解析器:视图解析器使用SpringMVC框架默认的InternalResourceViewResolver,这个视图解析器支持JSP视图解析。

<!-- 配置视图解析器 -->

<bean

class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<!-- 配置逻辑视图的前缀 -->

<property name="prefix" value="/WEB-INF/jsp/" />

<!-- 配置逻辑视图的后缀 -->

<property name="suffix" value=".jsp" />

</bean>

最终jsp物理地址:前缀+逻辑视图名+后缀


     3、参数类型推荐使用包装数据类型,因为基础数据类型不可以为null。

 

    4、SpringMVC与struts2的不同

  1. SpringMVC的入口是一个servlet即前端控制器,而struts2入口是一个filter过滤器。
  2. SpringMVC是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
  3. Struts2采用值栈存储请求和响应的数据,通过OGNL存取数据, SpringMVC通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。Jsp视图解析器默认使用jstl。

猜你喜欢

转载自blog.csdn.net/qq_33612051/article/details/83099531