SpringMVC学习笔记(2)

响应数据和结果视图

返回值分类

String

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping("/testString")
public String testString(Model model){
System.out.println("testString方法执行了。。。");

User user = new User();
user.setUsername("佩佩");
user.setPassword("123123");
user.setAge(18);

model.addAttribute("user", user);

return "success";
}

void

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("testVoid方法执行了。。。");
// 1. request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
// 2. response.sendRedirect("testString");
// 3.
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("你好");
}

ModelAndView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
System.out.println("testModelAndView方法执行了。。。");
ModelAndView mv = new ModelAndView();
User user = new User();
user.setUsername("小佩");
user.setPassword("123");
user.setAge(18);
// 把user对象存储到mv对象中,也会把user对象存入到request对象
mv.addObject("user", user);
// 跳转到哪个页面
mv.setViewName("success");
return mv;
}

转发和重定向

1
2
3
4
5
6
7
@RequestMapping("/testForwardAndRedirect")
public String testForwardAndRedirect(){
System.out.println("testForwardAndRedirect方法执行了。。。");

// return "forward:/WEB-INF/pages/success.jsp";
return "redirect:testString";
}

@ResponseBody响应json数据

  1. 引入jquery和jacksonjar包

    • json字符串和JavaBean对象互相转换的过程中,需要使用jackson的jar包
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
      </dependency>
      <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
      </dependency>
      <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
      </dependency>
  2. 配置前端控制器,让它不拦截静态资源

    1
    2
    3
    4
    <!-- 设置静态资源不过滤 -->
    <mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
    <mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
    <mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
  3. 编写页面发送ajax请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $(function () {
    $("#btn").click(function () {
    // alert("hello btn");
    // 发送ajax请求
    $.ajax({
    url:"user/testAjax",
    contentType:"application/json;charset=UTF-8",
    data:'{"username":"myhere","password":"123","age":30}',
    dataType:"json",
    type:"post",
    success:function (data) {
    // date服务器端响应的json的数据,进行解析
    alert(data);
    alert(data.username);
    alert(data.password);
    alert(data.age);
    }
    });
    });
    })
  4. 编写UserController,通过@ResponseBody标签可以直接将返回值转换为json传至前端页面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /**
    * 模拟异步请求
    */
    @RequestMapping("/testAjax")
    public @ResponseBody User testAjax(@RequestBody User user){
    System.out.println("testAjax方法执行了。。。");
    // 客户端发送ajax请求,传的是json字符串,后端把字符串封装到user对象中
    System.out.println(user);
    // 作响应,模拟数据库查询
    user.setUsername("meng");
    user.setAge(20);
    // 作响应
    return user;
    }

Spring实现文件上传

传统方式

  1. 导入文件上传的jar包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
    </dependency>
    <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
    </dependency>
  2. 编写文件上传的JSP页面

    1
    2
    3
    4
    5
    <h3>文件上传</h3>
    <form action="user/fileupload" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="upload"/><br/>
    <input type="submit" value="上传文件"/>
    </form>
  3. 编写文件上传的Controller控制器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    /**
    * 文件上传
    * @throws Exception
    */
    @RequestMapping(value="/fileupload")
    public String fileupload(HttpServletRequest request) throws Exception {
    // 先获取到要上传的文件目录
    String path = request.getSession().getServletContext().getRealPath("/uploads");
    // 创建File对象,一会向该路径下上传文件
    File file = new File(path);
    // 判断路径是否存在,如果不存在,创建该路径
    if(!file.exists()) {
    file.mkdirs();
    }
    // 创建磁盘文件项工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload fileUpload = new ServletFileUpload(factory);
    // 解析request对象
    List<FileItem> list = fileUpload.parseRequest(request);
    // 遍历
    for (FileItem fileItem : list) {
    // 判断文件项是普通字段,还是上传的文件
    if(fileItem.isFormField()) {
    }else {
    // 上传文件项
    // 获取到上传文件的名称
    String filename = fileItem.getName();
    // 上传文件
    fileItem.write(new File(file, filename));
    // 删除临时文件
    fileItem.delete();
    }
    }
    return "success";
    }

SpringMVC传统方式文件上传

  1. 配置文件解析器对象

    1
    2
    3
    4
    <!--文件解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10485760"></property>
    </bean>
  2. 编写UserController

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @RequestMapping("/fileUpload1")
    public String fileUpload1(HttpServletRequest request, MultipartFile upload) throws Exception {
    System.out.println("SpringMVC文件上传");
    // 文件位置
    String path = request.getSession().getServletContext().getRealPath("/uploads/");
    File file = new File(path);
    if (!file.exists()){
    // 如果没有这个文件夹就创建这个文件夹
    file.mkdirs();
    }

    // 获取上传文件名
    String filename = upload.getOriginalFilename();
    // 将文件名称设置为唯一值
    String uuid = UUID.randomUUID().toString().replace("-", "");
    filename = uuid + "_" + filename;
    upload.transferTo(new File(path,filename));
    return "success";
    }

跨服务器文件上传

  1. 导入坐标

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-core</artifactId>
    <version>1.18.1</version>
    </dependency>
    <dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.18.1</version>
    </dependency>
  2. 配置文件解析器对象

    1
    2
    3
    4
    <!--文件解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10485760"></property>
    </bean>
  3. index.jsp

    1
    2
    3
    4
    5
    <h3>跨服务器文件上传</h3>
    <form action="user/fileUpload2" method="post" enctype="multipart/form-data">
    请选择文件:<input type="file" name="upload"><br>
    <input type="submit" value="上传">
    </form>
  4. UserController

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
    * 跨服务器文件上传
    * @param upload 这个名称必须和文件项的name一模一样
    * @return
    */
    @RequestMapping("/fileUpload2")
    public String fileUpload2(MultipartFile upload) throws Exception {
    System.out.println("跨服务器文件上传");
    //定义上传文件服务器路径
    String path = "http://localhost:9090/uploads/";
    // 获取上传文件名
    String filename = upload.getOriginalFilename();
    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";
    }

异常处理

  1. 编写自定义异常类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
    * 自定义异常类
    */
    public class SysException extends Exception {
    private String message;

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

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

    public SysException(String message) {
    this.message = message;
    }
    }
  2. 编写异常处理器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /**
    * 异常处理器
    */
    public class SysExceptionResolver implements HandlerExceptionResolver {
    /**
    * 处理异常的业务逻辑
    * @param httpServletRequest
    * @param httpServletResponse
    * @param o
    * @param e
    * @return
    */
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
    SysException sysException = null;
    if (e instanceof SysException){
    sysException = (SysException) e;
    } else {
    sysException = new SysException("系统正在维护!");
    }

    ModelAndView mv = new ModelAndView();
    mv.addObject("errorMsg", sysException.getMessage());
    mv.setViewName("error");
    return mv;
    }
    }
  3. 配置异常处理器

    1
    2
    <!--配置异常处理器-->
    <bean id="eptionResolver" class="com.xushui.exception.SysExceptionResolver"></bean>

SpringMVC拦截器

拦截器作用

  • Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。 用户可以自己定义一些拦截器来实现特定的功能。
  • 谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
  • 拦截器和过滤器的区别:
    • 过滤器是servlet规范中的一部分,任何java web工程都可以使用。
    • 拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
    • 过滤器在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截。
    • 拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的。
  • 它也是 AOP 思想的具体应用。
  • 我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口。

自定义拦截器的步骤

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    public class MyInterceptor implements HandlerInterceptor {
    /**
    * 预处理,Controller方法执行前
    * @param request
    * @param response
    * @param handler
    * @return
    * true: 放行,执行下一个拦截器,如果没有,执行Controller方法
    * false: 不放行,可以用request或者response转发
    * @throws Exception
    */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("拦截器预处理方法执行了111111");
    // 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("拦截器后处理方法执行了11111");
    }

    /**
    * 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("拦截器afterCompletion方法执行了....1111111");
    }
    }
  2. 在bean.xml中配置拦截器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <!--配置拦截器-->
    <mvc:interceptors>
    <!--配置拦截器-->
    <mvc:interceptor>
    <!--要拦截的具体方法-->
    <mvc:mapping path="/user/*"/>
    <!--不要拦截的方法-->
    <!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
    <!--配置拦截器对象-->
    <bean id="myInterceptor" class="com.xushui.interceptor.MyInterceptor"></bean>
    </mvc:interceptor>

    <!--配置第二个拦截器-->
    <mvc:interceptor>
    <!--要拦截的具体方法-->
    <mvc:mapping path="/user/*"/>
    <!--不要拦截的方法-->
    <!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
    <!--配置拦截器对象-->
    <bean id="myInterceptor2" class="com.xushui.interceptor.MyInterceptor2"></bean>
    </mvc:interceptor>
    </mvc:interceptors>
  3. 当配置了两个拦截器后执行结果

    1
    2
    3
    4
    5
    6
    7
    8
    拦截器预处理方法执行了111111
    拦截器预处理方法执行了222222
    testInterceptor执行...
    拦截器后处理方法执行了22222
    拦截器后处理方法执行了11111
    success.jsp执行了...
    拦截器afterCompletion方法执行了....22222
    拦截器afterCompletion方法执行了....1111111

拦截器中断流程

拦截器一放行拦截器二不放行,那么执行结果将是

1
2
3
拦截器预处理方法执行了111111
拦截器预处理方法执行了222222
拦截器afterCompletion方法执行了....1111111


评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×