Spring MVC常用技术及基本概念

什么是Spring MVC

用来简化基于MVC架构的web应用程序开发,属于Spring框架的一部分

Spring MVC的核心组件

  1. DispatcherServlet 前端控制器
  2. HandlerMapping 映射处理器
  3. Controller 处理器
  4. ModelAndView 模型和视图
  5. ViewResolver 视图解析器

##组件之间的相互关系

  1. 请求先发送给DispatcherServlet,DispatcherServlet收到请求之后,依据HandlerMapping的配置调用对应的Controller来处理。

  2. Controller将处理结果封装成ModelAndView,然后返回给DispatcherServlet。

  3. DispatcherServlet依据ViewResolver的解析,调用对应的jsp生成页面。

Spring MVC常用技术

jsp页面

<%@page pageEncoding="utf-8" contentType="text/html" %>
<html>
	<form action="login1.do" method="post">
		<p>用户名:<input type="text" name="username"></p>
		<p>密码:<input type="password" name="pwd"></p>
		<p><input type="submit" value="登入"></p>
	</form>
</html>

读取请求参数值的方式

  1. 通过request

  2. 通过@RequestParam

  3. 通过javabean

@RequestMapping("login2.do")
public String logins(HttpServletRequest req,
		@RequestParam("pwd")String password,User user){
	
	System.out.println(req.getParameter("username"));
	System.out.println(password);
	System.out.println(user);
	return "hello";
}

向页面传值

  1. 将数据绑订到request。

  2. 返回ModelAndView。

  3. 将数据绑订到ModelMap。

  4. 将数据绑订到session。

@RequestMapping("login3.do")
public String loginsss(String username,String pwd,HttpServletRequest request){
	//通过requeset传递username
	request.setAttribute("username", username);
	//通过session
	HttpSession session = request.getSession();
	session.setAttribute("pwd", pwd);
	return "success";
}


@RequestMapping("login4.do")
public ModelAndView login6(String username,String pwd){

	User user = new User(username,pwd);
	Map<String, Object> data = new HashMap<String,Object>();
	data.put("data",user);//页面直接${data}就能得到user
	ModelAndView mv = new ModelAndView("success",data);
	return mv;
}


@RequestMapping("login5.do")
public String log(String username,String pwd,ModelMap model){
	User user = new User(username,pwd);
	//需要注意的是ModelMap只能作为参数传入才有效,在方法里new传参无效
	model.addAttribute("user",user);
	return "success";
}

//演示向页面传值
@RequestMapping("login6.do")
public String logs(@ModelAttribute("user") User user){
	return "success";
}

重定向

@RequestMapping("login7.do")
public String redirect(String username){
	System.out.println(username);
	//当返回值为String时用redirect:路径
	return "redirect:hi.do";
}

@RequestMapping("login.do")
public ModelAndView redirects(String pwd){
	System.out.println(pwd);
	//当返回值为ModelAndView时用RedirectView,参数为重定向路径
	RedirectView view = new RedirectView("hi.do");
	return new ModelAndView(view);
}

解决中文乱码

为什么会有乱码?

表单提交时,浏览器会对中文参数值使用打开该表单所在页面时的字符集来编码。比如使用”utf-8”来编码。服务器端默认使用”iso-8859-1”来解码。所以会产生乱码。

如何解决?

在web.xml中配置springmvc提供的过滤器(CharacterEncodingFilter)。但需要注意的是

  1. 表单提交方式必须设置为”post”

  2. 页面编码与过滤器的初始化参数设置的编码要一致。

<filter>
	<filter-name>encodingFilter</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>
	<init-param>
		<param-name>forceEncoding</param-name>
		<param-value>true</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>

异常处理

使用Spring MVC提供的简单的异常处理器SimpleMappingExceptionResolver

  该种方式只需要在配置文件里进行配置即可

<!-- 配置spring MVC提供的简单异常处理 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
           <!-- 定义默认的异常处理页面,即系统出现<prop>未指定的异常时就跳转默认指定的页面 -->  
           <property name="defaultErrorView" value="erroe"/>  
           <!-- 定义异常处理页面用来获取异常信息的变量名,也可不定义,默认名为exception,即就一个异常对象,
                                       可以在页面获取该异常对象的信息-->  
           <property name="exceptionAttribute" value="ex" />  
           <!-- 指定异常类型,并给出相应页面 -->
           <property name="exceptionMappings">
             <props>
               <prop key="java.lang.NullPointerException">erroe1</prop>
               <prop key="entity.MyException">erroe2</prop>
             </props>
           </property>
</bean>

自定义异常处理器

  1.该种方式需要自定义一个类实现HandlerExceptionResolver接口,根据不同的异常类型采取相应的界面

public class MyMappingExceptionResolver implements HandlerExceptionResolver {

    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        
        //根据异常类型返回相应视图
        if(ex instanceof NullPointerException){
            return new ModelAndView("erroe1");
        }
        
        if(ex instanceof MyException){
            return new ModelAndView("erroe2");
        }
        
        //其他错误就返回erroe.jsp
        return new ModelAndView("erroe");
    }

}

  2.在配置文件里进行配置

<!-- 配置自定义异常处理器 -->
  <bean class="controller.MyMappingExceptionResolver"/>

使用@ExceptionHandler注解实现局部异常处理

该种方式只能针对单一控制器内的异常进行处理,即在哪个处理器(controller)使用该注解,则哪个处理器的异常方法就被处理

@Controller
public class ExceptionController {
    
    //但需要注意的是这只是一个局部异常处理注解,即只对当前控制器有效,对其他控制器无效
    //指定异常
    @ExceptionHandler(NullPointerException.class)
    public String ExceptionHandler(){
        
        return "erroe1";
    }
    
    //指定异常
    @ExceptionHandler(MyException.class)
    public String ExceptionHandler1(){
        
        return "erroe2";
    }
    
    //其他异常
    @ExceptionHandler(Error.class)
    public String ExceptionHandler2(){
        
        return "erroe";
    }
    
    @RequestMapping("exception.do")
    //测试系统异常
    public ModelAndView toTest1(){
        Map<String,Object> data = new HashMap<String,Object>(); 
        //故意制造一个空指针异常
        String str = null;
        str = str.substring(0, 5);
        data.put("data", str);
        ModelAndView mv = new ModelAndView("success",data);
        return mv;
    
    }
    
    @RequestMapping("exception1.do")
    //测试自定义异常
    public ModelAndView toTest2(){
        
        String str = null;
        
        if(str==null){
            throw new MyException("完了出错了");
        }
      
        Map<String,Object> data = new HashMap<String,Object>(); 
        data.put("data", str);
        ModelAndView mv = new ModelAndView("success",data);
        return mv;
        
    }
    
    @RequestMapping("exception2.do")
    //测试未指定异常
    public ModelAndView toTest3(){
       
        String str = "abc";
        
        //故意制造一个类型转换异常
        Integer.valueOf(str);
        
        Map<String,Object> data = new HashMap<String,Object>(); 
        data.put("data", str);
        ModelAndView mv = new ModelAndView("success",data);
        return mv;
        
    }
    
}

拦截器

什么是拦截器?

DispatcherServlet收到请求之后,如果有拦截器,则先执行拦截器的方法,然后再执行处理器的方法。

注意:

过滤器属于Servlet规范,而拦截器属于Spring框架。

如何实现拦截器?

1.实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter类

  二者的区别在于前者三个方法都得实现,后者可以根据实际需求重写想要的方法

/**
 *该方法是创建拦截器的第二种方法,实现HandlerIntercep
 *用来监控登入所消耗的时间
 * @author Administrator
 *
 */
public class MySecondInterceptor implements HandlerInterceptor {
    
    private long start_time;
    private long end_time;
    
    //处理器执行请求前
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        start_time=System.currentTimeMillis();
        System.out.println("第二个拦截器请求结束前:第二个拦截器的方法已经执行");
        return true;
    }
    //处理器执行请求结束后,视图层显示前(即控制器向前端发送页面前)
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
            System.out.println("第二个拦截器请求结束后:请求结束后执行");
    }
    
    //处理器完全执行请求后,即视图已经展示
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        end_time=System.currentTimeMillis();
        System.out.println("第二个拦截器请求完全结束后:登入共耗时"+(end_time-start_time)+"毫秒");
    }

}

/**
*  自定义拦截器,用来实现登入验证
* @author WQP
*
*/
public class MyFirstInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("第一个拦截器方法已经执行了");
        return true;
    }
       
}

2.在配置文件中配置拦截器

<!-- 定义拦截器 -->
<mvc:interceptors>
    <!-- 实现登入验证 -->
    <mvc:interceptor>
        <!-- 指定拦截路径 -->
        <mvc:mapping path="/**"/>
        <!-- 指定不需要拦截的路径 -->
        <mvc:exclude-mapping path="/tologin.do"/>
        <mvc:exclude-mapping path="/login.do"/>
        <!-- 注入拦截的类 -->   
        <bean class="ssm.test.interceptors.MyFirstInterceptor"/>
    </mvc:interceptor>
    <!-- 监控登入耗时 -->
    <mvc:interceptor>
        <!-- 指定拦截路径 -->
        <mvc:mapping path="/login.do"/>
        <!-- 注入拦截的类 -->   
        <bean class="ssm.test.interceptors.MySecondInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3.实现登入操作后的控制台输出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值