09-SpringMVC

2021-02-20  本文已影响0人  XAbo

请求方式和请求的数据格式;响应方式和响应的数据格式。

SpringMVC处理流程

@RequestMapping(value="/testXml",produces = "text/plain;charset=utf-8"):接收请求,默认响应是跳转页面,producesconsumer是设置HTTP请求头和HTTP响应头的Content-Type
@ResponseBody:表示返回的数据,不进行页面跳转。注:返回json格式数据,要么自己封装要么开启注解驱动。返回xml数据要么自己封装要么在返回的Bean对象使用@XmlRootElement注解。

@Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用;
@RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

<mvc:annotation-driven />会先判断响应数据是否能按照返回类型进行转换,如果能则自动尝试转化(依据实现了哪种HttpMessageConverter)。

一、处理请求和响应

1.1 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 开启注解扫描 -->
    <context:component-scan base-package="cn.itcast"/>
    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--前端控制器,处理静态资源-->
    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/images/" mapping="/images/**"/>
    <mvc:resources location="/js/" mapping="/js/**"/>
    <!-- 开启SpringMVC框架注解的支持 -->
    <mvc:annotation-driven />
</beans>
annotation-driven

1.2 请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String basePath = request.getScheme()+"://" +
         request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
    <base href="<%=basePath%>">
    <title>My Sample</title>
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script>
        // 页面加载,绑定单击事件
        $(function(){

            $("#json_1").click(function(){
                $.ajax({
                    type:"post",
                    url:"testAjaxJson1",
                    contentType:"application/json;charset=UTF-8",
                    data:'{"username":"json","password":"123","age":30}',
                    dataType:"json",
                    success:function(data){
                        alert("账号:"+data.username+"密码:"+data.password+" 年龄"+data.age);
                    }
                });
            });

            $("#json_2").click(function(){
                $.ajax({
                    type:"post",
                    url:"testAjaxJson2?name=zhangsan",
                    contentType:"application/text;charset=UTF-8",
                    complete(XMLHttpRequest, textStatus){
                        alert("1");
                    }
                });
            });

            $("#json_3").click(function(){
                $.ajax({
                    type:"post",
                    url:"testAjaxJson3?name=zhangsan",
                    contentType:"application/text;charset=UTF-8",
                    dataType:"text",
                    success:function(data){
                        alert(data);
                    }
                });
            });

            $("#json_4").click(function(){
                var xmlData ="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><requestBody>\n" +
                    "<username>xml</username>\n" +
                    "<password>123</password>\n" +
                    "<age>30</age>\n" +
                    "</requestBody>";
                $.ajax({
                    type:"post",
                    url:"testAjaxJson4",
                    contentType:"application/xml",
                    data: xmlData ,
                    dataType:"xml",
                    success:function(data){
                        alert(data);
                    }
                });
            });
        });
    </script>
</head>
<body>
//带“/”和不带“/”区别
/**
1. 带“/” 是相对路径,相对的项目根路径:http://localhost:8080/test1。不含项目名称,所以test1必须写上项目名称
2.不带“/”是参考路径,参考当前页面地址栏中的地址, 项目启动后地址栏http://localhost:8080/Web,含项目地址所以,不需要写项目名称
3.建议做法:
<%    
 String basePath = request.getScheme()+"://" +
       request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/"; 
%>    
**/

test1:<a href="/Web/test1?name=zhangsan&age=12">test1</a><br>
test2:<a href="test2?username=lisi&age=22">test2</a><br>
test3:<a href="test3?username=lisi&age=23">test3</a><br>
test4:<a href="test4?username=lisi&age=23">test4</a><br>
test5:<a href="test5/lisi">test5</a><br>
test6:<form action="test6" method="post">
    <label>姓名</label>
    <input type="text"  name="username"><br>
    <label>密码</label>
    <input type="text" name="password"><br>
    <label>年龄</label>
    <input type="text" name="age"><br>
    <label>ID</label>
    <input type="text" name="id"><br>
    <input type="submit" tabindex="4" value="test6">
</form><hr/>
<button id="json_1">发送ajax的JSON POST请求</button>
<button id="json_2">发送ajax的TEXT GET请求 无响应</button>
<button id="json_3">发送ajax的TEXT GET请求</button>
<button id="json_4">发送ajax的XML  POST请求</button><
<hr/>
testRequestHeader:<a href="testRequestHeader">testRequestHeader</a><br>
testCookieValue:<a href="testCookieValue">testCookieValue</a><br>
testSessionAttributes:<a href="testSessionAttributes">testSessionAttributes</a><br>
getSessionAttributes:<a href="getSessionAttributes">getSessionAttributes</a><br>
delSessionAttributes:<a href="delSessionAttributes">delSessionAttributes</a>
</body>
</html>

1.3 处理和响应

@Controller
//注解只用作用在 类 上,作用是将指定的 Model 的键值对保存在 session 中。
//可以让其他请求共用 session 中的键值对
@SessionAttributes(value={"msg"})
public class UserController {
    @Autowired
    private UserService userServiceImpl;
    //---------------------SpringMvc知识点1:请求和响应START--------------------
    /*test1:
    * 1.请求内容:String
    * 2.请求方式:get
    * 3.参数格式:请求参数名称与接收参数名称部分一致
    * 4.处理请求:按照参数名和类型赋值
    * 5.响应内容:model and view
    * */
    @RequestMapping(value = "/test1")
    public ModelAndView test1(@RequestParam(name = "name") String userName,Integer age){
        UserDto userDto = new UserDto();
        userDto.setAge(age);
        userDto.setUsername(userName);
        ModelAndView mv = new ModelAndView();
        mv.setViewName("result");
        mv.addObject(userDto);
        return mv;
    }

    /*test2:
     * 1.请求内容:String
     * 2.请求方式:get
     * 3.参数格式:请求参数名称与接收参数名称一致
     * 4.处理请求:使用DTO接收,@ModelAttribute将请求参数赋值给对象
     * 5.响应内容:model and view
     * */
    @RequestMapping(value = "/test2")
    public String test2(@ModelAttribute UserDto userDto, Model model){
        model.addAttribute("userDto", userDto);
        return "result";
    }
    /*test3:
     * 1.请求内容:String
     * 2.请求方式:get
     * 3.参数格式:请求参数名称与接收参数名称一致
     * 4.处理请求:使用DTO接收,@ModelAttribute将请求参数赋值给对象
     * 5.响应内容:null ,使用@ResponseBody,否则找不到test3.jsp
     * */
    @RequestMapping(value = "/test3")
    @ResponseBody
    public void test3(@ModelAttribute UserDto userDto){

    }
    /*test4:
     * 1.请求内容:对象
     * 2.请求方式:get
     * 3.参数格式:请求参数名称与接收参数名称一致
     * 4.处理请求:使用DTO接收,@ModelAttribute将请求参数赋值给对象
     * 5.响应内容:model
     * */
    @RequestMapping(value = "/test4")
    public void test4(@ModelAttribute UserDto userDto, HttpServletRequest request, HttpServletResponse response){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        try {
            response.getWriter().print(request.getParameter("username")+"你好");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return;
    }
    /*test5:
     * 1.请求内容:String
     * 2.请求方式:get
     * 3.参数格式:restFul
     * 4.处理请求: @PathVariable解析路径中的值
     * 5.响应内容: mode and view
     * */
    @RequestMapping(value = "/test5/{name}")
    public String test5(@PathVariable(name="name") String name, Model model){
        // 底层会存储到request域对象中
        model.addAttribute("userDto", name);
        return "result";
    }
    /*test6:
     * 1.请求内容:对象
     * 2.请求方式:post
     * 3.参数格式:表单
     * 4.处理请求: @ModelAttribute
     * 5.响应内容: model and view
     * */
    @RequestMapping(value = "/test6")
    public String test6(@ModelAttribute UserDto userDto, Model model){
        // 底层会存储到request域对象中
        model.addAttribute("userDto", userDto);
        return "result";
    }
    /*testAjaxJson1:
     * 1.请求内容:对象
     * 2.请求方式:ajax
     * 3.参数格式:json
     * 4.处理请求: @RequestBody 解析XML或者json
     * 5.响应内容: model(json)
     * */
    @RequestMapping(value = "/testAjaxJson1")
    @ResponseBody
    public User testAjaxJson1(@RequestBody User user){
        return user;
    }
    /*testAjaxJson2:
     * 1.请求内容:string
     * 2.请求方式:ajax
     * 3.参数格式:json
     * 4.处理请求: @RequestBody 解析XML或者json
     * 5.响应内容: null
     * */
    @RequestMapping("/testAjaxJson2")
    public void testAjaxJson2(String name){
        return  ;
    }
    /*testAjaxJson3:
     * 1.请求内容:string
     * 2.请求方式:ajax
     * 3.参数格式:json
     * 4.处理请求: @RequestBody 解析XML或者json
     * 5.响应内容: model(string)
     * */
    @RequestMapping("/testAjaxJson3")
    @ResponseBody
    public String testAjaxJson3(String name){
        return name ;
    }
    /*testAjaxJson4:
     * 1.请求内容:对象
     * 2.请求方式:ajax
     * 3.参数格式:xml
     * 4.处理请求: @RequestBody 解析XML或者json
     * 5.响应内容: model(xml)
     * */
 
 @RequestMapping(value="/testAjaxJson4",consumes="application/xml")
    @ResponseBody
    public UserDto testAjaxJson4(@RequestBody UserDto user){
        return user;
    }

    /*
     * testRequestHeader
     * */
    @RequestMapping(value="/testRequestHeader")
    public void testRequestHeader(@RequestHeader(value="Accept") String header, HttpServletRequest request,HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        try {
            response.getWriter().print(header);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ;
    }
    /*
     * testCookieValue
     * */
    @RequestMapping(value="/testCookieValue")
    public void testCookieValue(@CookieValue(value="JSESSIONID") String cookieValue, HttpServletRequest request,HttpServletResponse response){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        try {
            response.getWriter().print(cookieValue);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return;
    }
    /*
     * SessionAttributes
     * */
    //设置
    @RequestMapping(value="/testSessionAttributes")
    @ResponseBody
    public void testSessionAttributes(Model model){
        // 底层会存储到request域对象中
        model.addAttribute("msg","薛增博");
    }
    //获取
    @RequestMapping(value="/getSessionAttributes")
    public void getSessionAttributes(ModelMap modelMap,HttpServletResponse response){
        String userDto = (String) modelMap.get("msg");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        try {
            response.getWriter().print(userDto);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return;
    }
    // 清除
    @RequestMapping(value="/delSessionAttributes")
    public void delSessionAttributes(SessionStatus status,ModelMap modelMap,HttpServletResponse response){
        status.setComplete();
        String userDto = (String) modelMap.get("msg");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        try {
            response.getWriter().print(userDto);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 请求的转发
        // return "forward:/WEB-INF/pages/success.jsp";
        // 重定向
        //return "redirect:/index.jsp";
        return ;
    }

    //-------------SpringMvc知识点1:请求和响应 END------------

}

二、文件上传

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="cn.itcast"/>
    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/images/" mapping="/images/**"/>
    <mvc:resources location="/js/" mapping="/js/**"/>
    <!--配置文件解析器对象-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760" />
    </bean>
    <!-- 开启SpringMVC框架注解的支持 -->
    <mvc:annotation-driven />
</beans>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>传统文件上传</h3>
    <form action="/user/fileupload1" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload" /><br/>
        <input type="submit" value="上传" />
    </form>

    <h3>Springmvc文件上传</h3>
    <form action="/user/fileupload2" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload" /><br/>
        <input type="submit" value="上传" />
    </form>

    <h3>跨服务器文件上传</h3>
    <form action="/user/fileupload3" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload" /><br/>
        <input type="submit" value="上传" />
    </form>
</body>
</html>
@Controller
@RequestMapping("/user")
public class UserController {
    // 跨服务器文件上传
    @RequestMapping("/fileupload3")
    public String fileuoload3(MultipartFile upload) throws Exception {
        System.out.println("跨服务器文件上传...");

        // 定义上传文件服务器路径
        String path = "http://localhost:9090/uploads/";
        // 说明上传文件项
        // 获取上传文件的名称
        String filename = upload.getOriginalFilename();
        // 把文件的名称设置唯一值,uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid+"_"+filename;
        // 创建客户端的对象
        Client client = Client.create();
        // 和图片服务器进行连接
        WebResource webResource = client.resource(path + filename);
        // 上传文件
        webResource.put(upload.getBytes());
        return "success";
    }

    // SpringMVC文件上传 
    @RequestMapping("/fileupload2")
    public String fileuoload2(HttpServletRequest request, MultipartFile upload) throws Exception {
        System.out.println("springmvc文件上传...");
        // 使用fileupload组件完成文件上传
        // 上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        // 判断,该路径是否存在
        File file = new File(path);
        if(!file.exists()){
            // 创建该文件夹
            file.mkdirs();
        }
        // 说明上传文件项
        // 获取上传文件的名称
        String filename = upload.getOriginalFilename();
        // 把文件的名称设置唯一值,uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid+"_"+filename;
        // 完成文件上传
        upload.transferTo(new File(path,filename));
        return "success";
    }

    // 文件上传
    @RequestMapping("/fileupload1")
    public String fileuoload1(HttpServletRequest request) throws Exception {
        System.out.println("文件上传...");
        // 使用fileupload组件完成文件上传
        // 上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        // 判断,该路径是否存在
        File file = new File(path);
        if(!file.exists()){
            // 创建该文件夹
            file.mkdirs();
        }
        // 解析request对象,获取上传文件项
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 解析request
        List<FileItem> items = upload.parseRequest(request);
        // 遍历
        for(FileItem item:items){
            // 进行判断,当前item对象是否是上传文件项
            if(item.isFormField()){
                // 说明普通表单向
            }else{
                // 说明上传文件项
                // 获取上传文件的名称
                String filename = item.getName();
                // 把文件的名称设置唯一值,uuid
                String uuid = UUID.randomUUID().toString().replace("-", "");
                filename = uuid+"_"+filename;
                // 完成文件上传
                item.write(new File(path,filename));
                // 删除临时文件
                item.delete();
            }
        }
        return "success";
    }
}

三、异常处理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="cn.itcast"/>
    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--前端控制器,哪些静态资源不拦截-->
    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/images/" mapping="/images/**"/>
    <mvc:resources location="/js/" mapping="/js/**"/>
    <!--配置异常处理器-->
    <bean id="sysExceptionResolver" class="cn.itcast.exception.SysExceptionResolver"/>
    <!-- 开启SpringMVC框架注解的支持 -->
    <mvc:annotation-driven />
</beans>
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/testException")
    public String testException() throws SysException{
        System.out.println("testException执行了...");
        try {
            // 模拟异常
            int a = 10/0;
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
            // 抛出自定义异常信息
            throw new SysException("查询所有用户出现错误了...");
        }
        return "success";
    }
}
public class SysException extends Exception{
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public SysException(String message) {
        this.message = message;
    }
}
public class SysExceptionResolver implements HandlerExceptionResolver{
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 获取到异常对象
        SysException e = null;
        if(ex instanceof SysException){
            e = (SysException)ex;
        }else{
            e = new SysException("系统正在维护....");
        }
        // 创建ModelAndView对象
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",e.getMessage());
        mv.setViewName("error");
        return mv;
    }
}

四、拦截器

Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。用户可以自己定义一些拦截器来实现特定的功能。

拦截器链(Interceptor Chain):拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。即可支配的资源不一样。

image.png
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

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

    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--前端控制器,哪些静态资源不拦截-->
    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/images/" mapping="/images/**"/>
    <mvc:resources location="/js/" mapping="/js/**"/>

    <!--配置拦截器-->
    <mvc:interceptors>
        <!--配置拦截器-->
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不要拦截的方法
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置拦截器对象-->
            <bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor1" />
        </mvc:interceptor>

        <!--配置第二个拦截器-->
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/**"/>
            <!--不要拦截的方法
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置拦截器对象-->
            <bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor2" />
        </mvc:interceptor>
    </mvc:interceptors>
    <!-- 开启SpringMVC框架注解的支持 -->
    <mvc:annotation-driven />
</beans>
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/testInterceptor")
    public String testInterceptor(){
        System.out.println("testInterceptor执行了...");
        return "success";
    }
}
public class MyInterceptor1 implements HandlerInterceptor{

    /**
     * 预处理,controller方法执行前
     * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法
     * return false不放行
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor1执行了...前1111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        return true;
    }

    // 后处理方法,controller方法执行后,success.jsp执行之前
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor1执行了...后1111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
    }

    //success.jsp页面执行后,该方法会执行   
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor1执行了...最后1111");
    }
}

五、SSM整合

确保配置文件加载顺序:
1.Spring:在Tomcat启动是利用监听器加载自己配置文件。
2.SpringMVC:自己的将Controller放入IOC,用自己配置文件即可。
3.Mybatis:将生成的代理DAO交给IOC即可(配置sqlSessionFactory)。

image.png
org.springframework.web.context.ContextLoaderListener监听器中的核心:AbstractApplicationContext.refresh()完成Bean初始化。
public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
                // Initialize message source for this context.
                initMessageSource();
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
                // Initialize other special beans in specific context subclasses.
                onRefresh();
                // Check for listener beans and register them.
                registerListeners();
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
                // Last step: publish corresponding event.
                finishRefresh();
            }

与bean初始化保持一致。

bean初始化
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--设置配置文件的路径 ServletContext容器配置参数,从而Spring提供的监听器读取配置文件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

  <!--解决中文乱码的过滤器-->
  <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>
 
  <!--配置Spring的监听器,默认只加载WEB-INF目录下的applicationContext.xml配置文件,使用context-param指定文件位置-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!--配置前端控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <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-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--开启注解的扫描,希望处理service和dao,controller不需要Spring框架去处理-->
    <context:component-scan base-package="cn.itcast" >
        <!--配置哪些注解不扫描-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!--Spring整合MyBatis框架-->
    <!--配置连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///ssm"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--配置SqlSessionFactory工厂-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--配置AccountDao接口所在包-->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.itcast.dao"/>
    </bean>

    <!--配置Spring框架声明式事务管理-->
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>

    <!--配置AOP增强-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.service.impl.*ServiceImpl.*(..))"/>
    </aop:config>
</beans>

springmvc.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启注解扫描,只扫描Controller注解-->
    <context:component-scan base-package="cn.itcast">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!--配置的视图解析器对象-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--过滤静态资源-->
    <mvc:resources location="/css/" mapping="/css/**" />
    <mvc:resources location="/images/" mapping="/images/**" />
    <mvc:resources location="/js/" mapping="/js/**" />

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

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>cn.itcast</groupId>
  <artifactId>ssm</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>ssm Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
    <slf4j.version>1.6.6</slf4j.version>
    <log4j.version>1.2.12</log4j.version>
    <mysql.version>5.1.6</mysql.version>
    <mybatis.version>3.4.5</mybatis.version>
  </properties>

  <dependencies>
    <!-- spring -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.6.8</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- log start -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>

    <!-- log end -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>

    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
      <type>jar</type>
      <scope>compile</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>ssm</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
上一篇下一篇

猜你喜欢

热点阅读