SpringMVC简介(常用注解,拦截器,异常处理)

SpringMVC的基本概念

什么是MVC
是一种基于两种形式,一种是C/S架构,也就是客户端/服务器,
另一种是B/S架构,也就是浏览器/服务器. 在JavaEE中,几乎全是基于B/S架构的开发,
那么在B/S架构中,系统标准的三层架构包括:表现层,业务层,持久层.

什么是SpringMVC?
SpringMVC是一种基于java实现的MVC设计模型的请求驱动类型的轻量级WEB框架,为目前最主流的MVC框架之一,他通过一套注解,让一个简单的java类成为处理请求的控制器,无需实现任何接口.同时还支持RESTful编程风格的请求
MVC设计模型:
M: model 模型 javaBean对象 一般用于封装数据
V: view 视图 JSP/Html 一般用于展示数据
C: Controller 控制器 Servlet 一般用于处理程序逻辑

SpringMvc和Struts2:

共同点:
他们都是表现层的框架,都是基于MVC模型编写的
他们的底层都离不开ServletAPI
他们的处理请求的机制都是一个核心控制器
区别:
SpringMVC的入口是Servlet , Struts2的入口是Filter
SpringMVC是基于方法设计的, Struts2是基于类设计的,Struts2每次执行都会创建一个动作类,而SpringMVC只会创建一个类,执行时调用类中的方法.
SpringMVC更加简洁,同时还支持JSR303,处理ajax的请求更方便
Struts2的OGNL表达式使页面的开发效率相比SpringMVC更高,但执行效率并没有比JSTL提升,尤其是struts2的表单标签,远没有html执行效率高.

SpringMVC搭建环境

在New Module的 Properties属性添加插件(解决maven项目创建过慢):
Name:archetypeCatalog Value:internal
创建java目录: java,resource目录

pom.xml文件

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <maven.compiler.source>1.7</maven.compiler.source>
 <maven.compiler.target>1.7</maven.compiler.target>
 <spring.version>5.0.2.RELEASE</spring.version>
</properties>

<!--Spring MVC依赖-->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
   <scope>provided</scope>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>${spring.version}</version>
</dependency>

web.xml文件配置:

<!--  前端控制器的配置-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    //springmvc提供的类
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  
    <!--加载springmvc.xml配置文件-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>

    <!--一般servlet只有当发送请求时才创建
       配置该参数,只要服务器一启动,就会创建servlet对象,
       servlet对象一创建,就会去加载springmvc.xml文件
    -->
    <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>dispatcherServlet</servlet-name> 
            <url-pattern>/</url-pattern>  / :不管发什么请求,都会经过servlet
        </servlet-mapping>

    <!--配置解决中文乱码的过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</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>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/</url-pattern>     / :不管发什么请求,都会经过过滤器
    </filter-mapping>

springmvc.xml文件配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
     
     <!--开启注解的扫描-->
     <context:component-scan base-package="com.tulun"></context:component-scan>
     <!--配置视图解析器-->
     <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <!--prefix: 文件所在的目录-->
         <property name="prefix" value="/WEB_INF/pages/"/>
         <!--文件的后缀名-->
         <property name="suffix" value=".jsp"/>
     </bean>

     <!--开启SpringMVC框架的注解的支持-->
     <mvc:annotation-driven/>
</beans>

index.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入门程序</h3>

    <a href="hello">入门程序</a>
</body>
</html>

HelloController.java文件:

//控制器的类 ,用来接收请求
@Controller
public class HelloController {
    //在方法上面添加请求的映射
    //(path="/hello"  那么以后/hello就是该方法的请求路径)
    @RequestMapping(path = "/hello")
public String sayHello() {
    System.out.println("Hello SpringMVC");
  //默认返回的值为当前jsp文件的名字
    return "success";
    }
}

WEB-INF目录下添加pages/success.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入门成功</h3>
</body>
</html>

SpringMVC运行的步骤

1.导入依赖
2.在web.xml配置前端控制器(在起启动服务器的时候就加载springmvc.xml文件)
3.在index.jsp文件创建一个链接 
入门程序
4.在springmvc.xml文件

 <!--开启注解的扫描-->
     <context:component-scan base-package="com.tulun"></context:component-scan>

当你点开该链接,就会去该包下的类查找index.jsp文件的 的值(也就是类中的方法)
5.找到之后

@RequestMapping(path="/hello")
public String sayHello() {
    System.out.println("Hello SpringMVC");
    //默认返回的值为当前jsp文件的名字
    return "success";
}

6.接下来在springmvc.xml文件配置视图解析器

<!--配置视图解析器-->
 <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <!--prefix: 文件所在的目录-->  
         <property name="prefix" value="/WEB-INF/pages/"/>
         <!--文件的后缀名-->
         <property name="suffix" value=".jsp"/>
 </bean>```

以上两个配置的意义:就会去在/WEB-INF/pages/目录下找名字为success.jsp的文件
所以需要在该目录下创建该文件success.jsp(例:此处为成功请求页面)

常用注解

@RequestMapping注解

用于建立请求URL和处理请求方法之间的对应关系
可以放在方法上,也可以是类
试例:

<a href="controller/testRequestMapping">RequestMapping注解</a>

@RequestMapping(path = "/controller")
public class HelloController {
     @RequestMapping(path = "/testRequestMapping")
     public String testRequestMapping() {
     }
}

属性:

value和path的作用是一样的

@RequestMapping(path = "/controller")
public class HelloController {
    @RequestMapping(value = "/testRequestMapping")
    public String testRequestMapping() {
    }
}

method: 请求方式

//method={RequestMethod.POST} 表示该方法的请求必须为 post 方式 (为枚举类型)
   @RequestMapping(path = "/testRequestMapping",method={RequestMethod.POST})
   public String testRequestMapping() {
   }

params: 请求的时候必须传入一个 username的参数 如果params = {“username=hehe”}传入的参数必须为这样 ?username=hehe

    @RequestMapping(path = "/testRequestMapping",params ={"username"})
    public String testRequestMapping() {
    }
<a href="controller/testRequestMapping?username=haha">RequestMapping注解</a>

@RequestParam:

把请求中指定名称的参数给控制器中的形参赋值

<a href="anno/testRequestParam?name=haha">RequestParam</a>

@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(value = "name") String username) {
  System.out.println("执行了...");
  return "success";
}

@RequestBody:

获取到请求体的内容

<form action="/anno/testRequestBody" method="post">
  姓名: <input type="text" name="username"/><br/>
  密码: <input type="text" name="age"/><br/>
  <input type="submit" value="提交"/>
</form>
/**
* 获取到请求体的内容
* @param body
* @return
*/
@RequestMapping("testRequestBody")
public String testRequestBody(@RequestBody String body) {
  System.out.println("执行了...");
  return "success";
}

@PathVaribale:

和restful风格很像 path="/user/{id}" 传一个占位符

  RESTful风格URL:
   优点:节后清晰,符合标准,易于理解,扩展方便,更利于缓存
原来方式:
    UserController类
path="/user/save"
save

path="/user/update"
update

path="/user/findAll"
findAll

restful方式: 根据不同的请求方式,找到方法执行
   UserController类
path="/user" post
save

path="/user"   put
update

path="/user"  get
findAll

path="/user/{id}"  get
findById(id)

localhost:8080/user/10  get(请求方式)   查询的是findById
localhost:8080/user       get 查询的是findAll

@SessionAttribute

anno.jsp文件

<%--SessionAttritubes--%>
<a href="anno/testSessionAttributes">SessionAttributes</a>
<a href="anno/getSessionAttribute">SessionAttributes</a>
<a href="anno/delSessionAttribute">SessionAttributes</a>

AnnoController.java

@SessionAttributes("msg")   //将数值存入Session域
public class AnnoController {
    
	/**
	 * testSessionAttributes注解  向session存值
	 * @return
	 */
	@RequestMapping("/testSessionAttribute")
	public String testSessionAttributes(Model model) {
	    System.out.println("testSessionAttributes...");
	    //将一组键值对存入model对象 会存储到Request域对象中
	    model.addAttribute("msg","meimei");
	    return "success";
	}
	/**
	 * 获取值
	 * @param modelMap
	 * @return
	 */
	@RequestMapping("/getSessionAttribute")
	public String testGetSessionAttributes(ModelMap modelMap) {
	    System.out.println("testSessionAttributes...");
	    String msg = (String)modelMap.get("msg");
	    System.out.println(msg);
	    return "success";
	}
	/**
	 * 删除值
	 * @param sessionStatus
	 * @return
	 */
	@RequestMapping("/delSessionAttribute")
	public String testDelSessionAttributes(SessionStatus sessionStatus) {
	    System.out.println("testSessionAttributes...");
	    //清空Session域
	    sessionStatus.setComplete();
	    return "success";
	}
}

success.jsp

                                          <!--说明不忽略EL表达式-->
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
${ requestScope }
${ sessionScope }

返回值

response.jsp文件

<a href="user/testString">TestString</a>

<a href="user/testVoid">TestVoid</a>

UserController.java文件

//返回值为字符串
@RequestMapping(path = "/testString")
public String testString(Model model) {
    System.out.println("testString...");
    //模拟从数据库中查询User对象
    User user = new User();
    user.setUname("fly");
    user.setAge(19);
    user.setDate(new Date());
    //model存对象
    model.addAttribute("user",user); //存入request域
    return "success";
}
//返回值为void  注:如果没有返回值,会默认去WEB-INF/pages/user/找testVoid.jsp文件
@RequestMapping(path = "/testVoid")
public void testVoid(HttpServletRequest request,HttpServletResponse response) throws Exception {
    System.out.println("testVoid...");
    //请求转发 手动转发不会调用视图解析器 所以要自己写路径
    request.getRequestDispatcher("WEB-INF/pages/success.jsp").forward(request,response);
    //重定向 会重定向请求index.jsp
    response.sendRedirect(request.getContextPath()+"/index.jsp");
    
    //设置中文乱码
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");
    //会直接进行响应
    response.getWriter().println("你好");
}

异常处理

     异常处理思路:Controller调用service ,service调用dao,异常都是向上抛出的,最终由DispatcherServlet异常处理器进行异常的处理.
    SpringMVC异常处理:在前端控制器配置一个 异常处理器(组件).

1.编写自定义异常类(做提示信息的)

public class SysException extends Exception{

    //存储提示信息
    private String message;

    public SysException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

2.编写异常处理器

public class SysExceptionResolver implements HandlerExceptionResolver {

    /**
     * 处理异常的业务逻辑
     * @param request
     * @param response
     * @param o
     * @param e
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        //获取异常对象
        SysException exception = null;
        if(e instanceof SysException) {
            exception = (SysException)e;
        } else {
            exception = new SysException("系统正在维护...");
        }

        //创建ModelAndView
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",exception.getMessage());
        //表示往哪去跳转
        mv.setViewName("error");
        return mv;
    }
}

3.配置异常处理器(跳转到提示页面)

<!--配置异常处理器-->
<bean id="sysExceptionResolver" class="com.tulun.exception.SysExceptionResolver"></bean>

SpringMVC拦截器

 拦截器是springMVC框架自己的,只有使用了SpringMVC框架后才能用
 过滤器是servlet规范中的一部分,任何web项目都可以使用
 拦截器只会拦截访问的控制器(Controller)的方法,如果访问的是jsp,html,css,image都不会拦截
 过滤器是url-pattern中配置了 /* 之后,对所有访问资源进行拦截

1.编写拦截器类 实现HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {
   /**
    * 预处理  在controller方法执行前执行
    * @param request
    * @param response
    * @param handler
    * @return  true:放行,执行下一个拦截器,如果没有,执行controller方法
    * @throws Exception
    */
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       System.out.println("拦截器执行了....前");
       //页面跳转
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
       return true;
   }

   /**
    * 后处理方法 在controller方法执行后 success.jsp执行之前
    * @param request
    * @param response
    * @param handler
    * @param modelAndView
    * @throws Exception
    */
   @Override
   public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
       System.out.println("拦截器执行了....后");
   }

   /**
    * 在success.jsp执行后执行
    * @param request
    * @param response
    * @param handler
    * @param ex
    * @throws Exception
    */
   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
       System.out.println("拦截器执行了....最后");
   }
}

2.配置拦截器

<!--配置拦截器-->
<mvc:interceptors>
    <!--配置拦截器-->
    <mvc:interceptor>
        <!--要拦截的具体的方法-->
        <mvc:mapping path="/user/*"/>
        <!--不要拦截的方法
        <mvc:exclude-mapping path=""/>-->
        <!--配置拦截器对象-->
        <bean id="myInterceptor" class="com.tulun.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值