SpringMVC框架–学习笔记(下)

SpringMVC框架–学习笔记(下)

接上篇:SpirngMVC框架–学习笔记(上):https://blog.csdn.net/a745233700/article/details/81038382

17、全局异常处理:

    系统中异常包括两类,预期异常和运行时异常RuntimeException,前者通过捕获异常从而获得异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

    系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

SpringMVC框架--学习笔记(下)

springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。

(1)自定义异常类:

对不同的异常类型定义异常类,继承Exception

//自定义异常:
//针对预期的异常,需要在此类中抛出此类的异常
public class CustomException extends Exception{
	
	private String message;
	public CustomException(String message)
	{
		super(message);
		this.message=message;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
}

(2)全局异常处理器:实现HandlerExceptionResolver接口

思路:

    系统遇到异常,在程序中手动抛出,dao抛给service、service给controller、controller抛给前端控制器,前端控制器调用全局异常处理器。

    全局控制器处理思路:

    ①解析出异常类型;

    ②如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示。

    ③如果该异常不是系统自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)

//自定义异常:
//针对预期的异常,需要在此类中抛出此类的异常
public class CustomException extends Exception{
	
	private String message;
	public CustomException(String message)
	{
		super(message);
		this.message=message;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
}

在springmvc文件中注册全局异常处理器:

       <!-- 全局异常处理器 -->
       <!-- 不用写id,系统根据是否实现HandlerExceptionResolver接口,
       		只要实现,就是全局异常处理器,如果配置多个,只有一个起作用 -->
       <bean class="com.zwp.ssm.exception.CustomExceptionResolver"></bean> 

SpringMVC框架--学习笔记(下)

如果与业务功能相关的异常,建议在service中抛出异常。

与业务功能没有关系的异常,建议在controller中抛出。

18、上传图片:

(1)创建图片虚拟目录:

①第一种:

SpringMVC框架--学习笔记(下)

②第二种:

也可以直接修改tomcat的配置:在conf/server.xml文件,添加虚拟目录:

SpringMVC框架--学习笔记(下)

注意:在图片虚拟目录中,一定将图片目录分级创建(提高I/O性能),一般我们采用按日期进行分级创建。

(2)加入上传图片的jar包:

SpringMVC框架--学习笔记(下)

(3)在页面的form表单中加入enctype=”multipart/form-data”

SpringMVC框架--学习笔记(下)

(4)在springmvc.xml文件中配置解析器:

       <!-- 上传文件 -->
       <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
       		<!-- 设置上传文件最大尺寸 -->
       		<property name="maxUploadSize">
       			<value>5242880</value>
       		</property>
       </bean>

(5)编写Controller:

	//MultipartFile items_pic用于接收图片
	@RequestMapping(value="/editItemsSubmit",method={RequestMethod.POST,RequestMethod.GET})
	public String editItemsSubmit(Model model,HttpServletRequest request,Integer id,
			@ModelAttribute("itemsCustom") @Validated(value={ValidGroup1.class}) ItemsCustom itemsCustom,
			BindingResult bindingResult,MultipartFile items_pic) throws Exception
	{
		
		if(bindingResult.hasErrors())
		{
			List<ObjectError> allErrors=bindingResult.getAllErrors();
			//自定义一个list接受自己编码后的提示字符串,在把自己定义的list传到界面,
            //这样就解决了把乱码传到界面的问题了
            List<String> listErrors=new ArrayList<>();

			for(ObjectError objectError:allErrors)
			{
				//System.out.println(objectError.getDefaultMessage());
				//把返回错误的提示再次编码
				String strError=new String(objectError.getDefaultMessage().getBytes("ISO-8859-1"),"UTF-8"); 
	            listErrors.add(strError);//把编码好的错误提示信息加自己定义好list集合里面去
			}
			model.addAttribute("allErrors", listErrors);
			return "Items/editItems";
		}
		
		//原始名称
		String originalFilename=items_pic.getOriginalFilename();
		System.out.println(originalFilename);
		//上传图片:
		if(items_pic!=null && originalFilename!=null && originalFilename.length()>0)
		{
			//存储图片的物理路径:
			String pic_path="D:\\Tomcat 5.5\\pictures\\";
		
			//新的图片名称
			String newFileName=UUID.randomUUID()+originalFilename.substring(originalFilename.lastIndexOf("."));
			//新图片:
			File newFile=new File(pic_path+newFileName);
	
			//将内存中的数据写入磁盘
			items_pic.transferTo(newFile);
			
			//将新图片名称写到itemsCustom中
			itemsCustom.setPic(newFileName);
		}
		
		//调用service更新商品信息,页面需要将商品信息传到此方法中
		itemsService.updateItems(id, itemsCustom);
				
		//页面转发:
		return "forward:queryItems.action";
	}

(6)页面显示:

SpringMVC框架--学习笔记(下)

19、json交互:

@RequestBody:将json串转成java对象

@ResponseBody:将java对象转成json输出。

(1)请求是Json串,输出也是json串。

SpringMVC框架--学习笔记(下)

(2)请求是key/value,输出是json(常用)

SpringMVC框架--学习笔记(下)

最终结果都是输出json数据,为了在前端页面方便对请求结果进行解析。

步骤:

第一步:导入jar包依赖:

SpringMVC框架--学习笔记(下)

第二步:配置json转化器:

在注解适配器中加入messageConverters

SpringMVC框架--学习笔记(下)

注意:如果使用<mvc:annotation-driver />则不用定义上边的内容。

第三步:页面和控制器:

SpringMVC框架--学习笔记(下)

SpringMVC框架--学习笔记(下)

SpringMVC框架--学习笔记(下)

SpringMVC框架--学习笔记(下)

SpringMVC框架--学习笔记(下)

SpringMVC框架--学习笔记(下)

SpringMVC框架--学习笔记(下)

20、springmvc对RESTful的支持:

(1)对url进行规范,写RESTful格式的url

SpringMVC框架--学习笔记(下)

(2)http的方法规范 :

不管是删除、添加、更新。。使用的url是一致的,如果进行删除,需要设置http的方法为delete,同理添加。

后台controller方法:判断http方法,如果是delete执行删除,如果是post执行添加。

(3)对http的contentType规范:

请求是指定contentType,要json数据,设置成json格式的type..

需求:查询商品信息,返回json数据。

思路:定义方法,进行url映射使用RESTful风格的url,将查询商品的信息的id传入controller。输出json是,使用@ResponseBody将java对象输出json。

(1)Controller:

SpringMVC框架--学习笔记(下)

	//根据id查找商品信息,使用RESTful风格,并返回json格式的数据
	//("/itemView/{id}")的id要和@PathVariable("id")的id一致,表示将("/itemView/{id}")的id绑定到@PathVariable后面的参数上面
	@RequestMapping("/itemView/{id}")
	public @ResponseBody ItemsCustom itemView(@PathVariable("id") Integer id) throws Exception
	{
		ItemsCustom itemsCustom=itemsService.findItemsById(id);
		return itemsCustom;
	}

(2)前端控制器配置:

	<!-- RESTful规范要用第二种方式: -->
	<servlet>
		<servlet-name>springmvc_restful</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
			
		<!-- contextConfigLocation:配置springmvc加载的配置文件(处理处映射器、处理器适配器等等) -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:/spring/springmvc.xml</param-value>
		</init-param>	 
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc_restful</servlet-name>
		<!-- 
		第一种:*.action,访问以.action结尾由DispatcherServlet进行解析
		第二种:/,所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置
				不让DispatcherServlet进行解析,使用此种方法可以实现RESTful风格的url
		第三种:/*,这种配置不对,使用这种配置,最终要转发到一个jsp页面,仍然会由
					DispatcherServlet解析jsp,不能根据jsp页面找到Handle,会报错-->
		<url-pattern>/</url-pattern>
	</servlet-mapping>

(3)访问的url:

SpringMVC框架--学习笔记(下)

(4)json结果数据:

SpringMVC框架--学习笔记(下)

–对静态资源的解析:

在springmvc.xml中添加静态资源的解析:

      <!-- 对静态资源的解析,如js,css,img... -->
      <!--  <mvc:resources location="/js/" mapping="/js/**"></mvc:resources> -->
      <!--  <mvc:resources location="/css/" mapping="/css/**"></mvc:resources> -->

对静态资源的访问:

SpringMVC框架--学习笔记(下)

21、springmvc拦截器:

(1)定义拦截器:实现HandlerInterceptor接口

public class HandlerInterceptor1 implements HandlerInterceptor{
	
	//进入Handler方法之前
	//用于身份认证,身份授权
	//比如身份认证,如果认证不通过表示当前用户没有登陆,需要此方法拦截不再向下执行
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {	
		//return false:表示拦截,不向下执行
		//return ture:表示放行
		System.out.println("HandlerInterceptor1...preHandle");
		return true;
	}

	//进去Handler方法之后,返回modelAndView之前执行
	//应用场景:将公用的模型数据(比如菜单导航)传到视图,也可以在这里统一制定视图
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
		System.out.println("HandlerInterceptor1...postHandle");
	}
	
	//执行Handler完成执行此方法
	//应用场景:统一异常处理,统一日志处理
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("HandlerInterceptor1...afterCompletion");
	}
}

(2)配置拦截器:

①针对HandlerMapping进行拦截配置:(一般不用)

如果在某个HandlerMapping中配置,经过该HandlerMapping映射成功的Handler最终使用该拦截器。

SpringMVC框架--学习笔记(下)

②类似全局的拦截器:

springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。

       <!-- 拦截器 -->
       <mvc:interceptors>
       		<!-- 多个拦截器:顺序执行 -->
      	 	<mvc:interceptor>
      	 		<!-- /**:表示拦截所有url包括子url路径 -->
       			<mvc:mapping path="/**"/>
       			<!-- 拦截器路径 -->
       			<bean class="com.zwp.ssm.intercept.HandlerInterceptor1"></bean>
      	 	</mvc:interceptor>
      	 	
      	 	<mvc:interceptor>
       			<mvc:mapping path="/**"/>
       			<bean class="com.zwp.ssm.intercept.HandlerInterceptor2"></bean>
      	 	</mvc:interceptor>    	 	
       </mvc:interceptors>

(3)测试:

①两个拦截器都放行:

SpringMVC框架--学习笔记(下)

总结:preHandle方法按顺序执行;postHandle和afterCompletion按拦截器配置的逆向顺序执行。

②拦截器1放行,拦截器2不放行:

SpringMVC框架--学习笔记(下)

总结:拦截器1放行,拦截器2的preHandle才会执行;

拦截器2的preHandle不放行,拦截器2的postHandle和afterCompletion不会执行;

只要有一个拦截器不放行,postHandle不会执行。

③拦截器1不放行,拦截器2不放行:

SpringMVC框架--学习笔记(下)

总结:拦截器1的preHandle不放行,postHandler和afterCompletion不会执行。

拦截器1的preHandle不放行,拦截器2不执行。

(4)拦截器小结:

根据测试结果,对拦截器应用。

比如:统一日志处理拦截器,需要该拦截器的preHandle一定要放行,且将它放在拦截器链中第一个位置。

比如:登陆认证拦截器,放在拦截器链中第一个位置;权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过之后才检验权限)

(5)拦截器应用:

需求:

①用户请求url

②拦截器进行拦截校验:

    –如果请求的url是公开地址(无需登陆即可访问的url),让放行。

    –如果用户session不存在,跳转到登陆页面

    –如果用户session存在,放行,继续操作。

登陆页面:

<form action="${pageContext.request.contextPath }/login.action" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登陆"/>
</form>

拦截器:

public class LoginInterceptor implements HandlerInterceptor{
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {	
		//获取请求的url
		String url=request.getRequestURI();
		//判断url是否是公开地址(实际使用时,将公开地址配置在配置文件中)
		//这里公开地址是登陆提交的地址
		if(url.indexOf("login.action")>=0){
			//如果进行登陆提交,放行
			return true;
		}
		//判断session
		HttpSession session=request.getSession();
		//从session中取出用户身份信息:
		String username=(String) session.getAttribute("username");
		if(username!=null)
		{	//身份存在,放行
			return true;
		}	
		//执行到这里,表示用户身份需要认证,跳转到登陆界面
		request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);	
		return false;		
	}
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3) throws Exception {

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3)
			throws Exception {
	}
}

注册拦截器:

       <!-- 拦截器 -->
       <mvc:interceptors>
       		<!-- 多个拦截器:顺序执行 -->
       		<mvc:interceptor>
      	 		<!-- /**:表示拦截所有url包括子url路径 -->
       			<mvc:mapping path="/**"/>
       			<!-- 拦截器路径 -->
       			<bean class="com.zwp.ssm.intercept.LoginInterceptor"></bean>
      	 	</mvc:interceptor>
       </mvc:interceptors>

编写Controller:

@Controller
public class LoginController {
	@RequestMapping("/login")
	public String login(HttpSession sesison,String username,String password) throws Exception{
		//调用service进行身份验证
		//...
		
		//保存用户身份信息
		sesison.setAttribute("username", username);
		//重定向到商品列表
		return "redirect:items/queryItems.action";	
	}
	
	@RequestMapping("/logout")
	public String logout(HttpSession sesison) throws Exception{
		
		//清除session
		sesison.invalidate();
		//重定向商品列表
		return "redirect:items/queryItems.action";		
	}
}

登陆成功页面:

SpringMVC框架--学习笔记(下)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114726.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • git如何移除某文件夹的版本控制

    git如何移除某文件夹的版本控制

    2021年10月20日
  • 打造一个红旗(redflag)Linux的基础镜像(base image)「建议收藏」

    打造一个红旗(redflag)Linux的基础镜像(base image)「建议收藏」起因由于工作原因,想找一个红旗Linux的基础镜像(baseimage)。网上搜了一下,但没有现成的。起初是想找对应的centos版本来代替,但又怕有些莫名其妙的问题。官方文档不过搜索过程中,

  • Android源码学习之环境搭建(Ubuntu下载Android源码)

    Android源码学习之环境搭建(Ubuntu下载Android源码)已经有一个多月没有看Android的知识了,之前在杭州时就买了邓凡平的《深入理解Android卷I》一直没来得及研究。后来因为公司要求,要为新的项目做准备,做各种业务的KT和技术的training,虽然新技术本身的难度不大,但是业务知识很是复杂,搞的头大,到现在终于有了一些头绪。趁现在有时间来研究下Android的源码。之前没有接触过Linux系统,我的本本现在用的是Windows系统,已经用习

  • python少儿趣味编程案例(python少儿编程书)

    Python简单易学,功能强大,是少儿学习编程的首选语言。本书是少儿学习Python编程的趣味指南,全书共17章,按照由简到难、逐步深入的方式组织各章内容。本书从认识Python开始,首先介绍了Python的安装和IDLE的使用,然后依次介绍了变量、数字和字符串、列表、元组和字典、布尔类型等数据类型,以及条件、循环、异常和注释、函数、面向对象编程、文件操作等基础知识,并且通过实际案例讲解了海龟绘图…

  • linux常用命令50个_docmd常用命令详解

    linux常用命令50个_docmd常用命令详解1. find基本语法参数如下:find[PATH][option][action]#与时间有关的参数:-mtimen:n为数字,意思为在n天之前的“一天内”被更改过的

  • 卡盟销售官网源码php,卡盟整站程序源码 php版「建议收藏」

    卡盟销售官网源码php,卡盟整站程序源码 php版「建议收藏」卡盟整站源码是该网站的内核程序,内核是Ecshop,类似平台开钻之类整站程序,也是重要的源码文件,其中包含了各种源码类型文件,比较全,安装操作比较简单。卡盟整站源码是一个点卡销售/充值平台程序,可以开钻,自动发货点卡,充值点卡,充值QB,如果自己想搭建卡盟的朋友可以下载使用。卡盟整站程序源码功能模块介绍系统公告、行业新闻、帮助信息、网址导航、用户注册,购卡中心。后台可以进行商品管理、订单管理、用户…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号