Java之SpringMVC核心知识详解

SpringMVC 批量删除

批量删除需要传递一堆id 所以参数类型为整型数组

<input type="checkbox" value="${item.s_id }" name="ids">

@RequestMapping("deleteStudents.action")
public String deleteStudents(Integer[] ids) {
    System.out.println(Arrays.toString(ids));
    return "forward:getStudents.action";
}

SpringMVC 批量修改

数据比较复杂 SpringMVC中不支持list直接作为参数 使用包装类来接收
用来包装Student集合

public class Studenteger {
    private List<Student> stus;

    public List<Student> getStus() {
        return stus;
    }

    public void setStus(List<Student> stus) {
        this.stus = stus;
    }

    @Override
    public String toString() {
        return "Studenteger [stus=" + stus + "]";
    }
}

前端页面

<td><input value="${item.s_name }" name="stus[${s.index }].s_name"></td>
<td><input value="${item.s_age }" name="stus[${s.index }].s_age"></td>
<td><input value="${item.s_gender }" name="stus[${s.index }].s_gender"></td>

处理器

@RequestMapping("updateStudents.action")
public String updateStudents(Studenteger s) {
    System.out.println(s);
    return "forward:getStudents.action";
}

SpringMVC 自定义参数转换器

Student更新时 需要传递 姓名 性别 年龄
姓名 性别 是字符串类型
年龄是整型 能够确定的是前台传递的参数是String类型
请求参数到达Controller方法前必然要经过转换
因此需要自定义参数转换器

所谓自定义参数转换器指定就是转换参数类型的具体代码

具体操作(实例String转Integer)
创建参数转换器 实现Converter接口

public class MyIntConverter implements Converter<String, Integer> {

    @Override
    public Integer convert(String param) {
        System.out.println(param);
        // 将字符串分割为单个字符
        // 提取值在0-9之间的字符组成新的整型
        char[] charArray = param.toCharArray();
        String newParam = "";
        for (char c : charArray) {
            if (c >= '0' && c <= '9') {
                newParam += c;
            }
        }
        System.out.println("转换后的参数" + newParam);
        return Integer.valueOf(newParam);
    }

}

在配置文件注册需要的转换器

<!-- 注册自定义参数转化器 -->
<mvc:annotation-driven conversion-service="converters"></mvc:annotation-driven>

<bean name="converters" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <bean class="com.lanou.converter.MyIntConverter"></bean>
    </property>
</bean>


SpringMVC框架会在接收到请求后 自动执行转换器中的代码 最后将转换结果交给Controller使用

@RequestMapping注解 详解

用来将请求路径与处理器的分发进行绑定
value 类型: 数组

支持一个或多个字符串
    多个需要用大括号包裹
    例如:@RequestMapping(value={"test","myTest"})
    此时无论请求test还是mytest都会执行对应的方法

method 类型: RequestMethod枚举数组

一个或多个 
注意:如果设置为单个POST那该请求仅支持POST 如果类型不匹配会抛出异常(GET也一样)

多个需要用大括号包裹 例如
    method= {RequestMethod.POST,RequestMethod.GET}

consumes 类型: 字符串

用于设置请求支持的Content-type 一般不做修改 支持任何类型的Content-type

produces 类型: 字符串

用于设置返回数据的Content-type(告诉浏览器如何解析)
该属性通常用于设置返回数据的编码
    例如:produces="text/html;charset=utf-8"

params 类型: 字符串数组

用于限制请求需要的参数和条件
    例如 params="id=100"
    表示该请求必须包含id参数 并且值必须为100

headers 类型: 字符串数组

用于设置Header请求头中所包含的键值对

SpringMVC异常处理

处理机制:
        dao层抛给Service抛给Controller抛给控制器
        核心控制器会在容器中找一个异常处理器对象

1.创建异常处理类 实现HandlerExceptionResolver

public class MyExceptionHandle implements HandlerExceptionResolver{

    // 当在处理某个请求方式异常时 将自动调用该方法进行处理
    // 第三个参数表示异常位置
    // 返回值 ModelAndView 用来决定错误时显示的页面 以及数据
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object location,
            Exception e) {
        System.out.println("异常发生的位置" + location);
        System.out.println("异常" + e);
        // 发生异常后进入exception.jsp
        // 并将位置和错误信息传给页面展示
        // 对于系统异常 我们没有办法具体处理 因为不知道为什么发生
        // 对于自己定义的已知异常 就可以进行具体的处理
        ModelAndView mv = new ModelAndView();
        if (e instanceof MyException) {
            System.out.println(((MyException) e).getMsg());
            mv.addObject("msg", ((MyException) e).getMsg());
        }
        mv.setViewName("exception.jsp");
        mv.addObject("location", location);
        return mv;
    }

}

2.将这个类注册到容器中

<!-- 配置异常处理器 -->
<bean class="com.lanou.exception.MyExceptionHandle"></bean>

使用异常处理器 对于自定义可以根据不同异常进行具体的处理

    @RequestMapping("getStudents.action")
    public String getStudents(Model model) {

        // 模拟异常
        //int a = 1/0;


        List<Student> students = studentService.getStudents();

        // 使用自定义的异常
        if (students.size() < 10) {
            throw new MyException("人数不够");
        }

        // 将数据放到model中
        model.addAttribute("student", students);
        return "list.jsp";
    }

SpringMVC 文件上传

实现给学生上传头像

1.给学生表添加头像字段保存图片路径
2.修改响应的实体类与映射文件

思路:
    上传文件后保存到指定的路径
    数据库中存储图片的名字
        1.通常我们会将收到的文件放在服务器的某个路径下
        不要放在编辑器中  因为Tomcat发布项目时是为其创建了一个新的路径
        这样会导致一个问题 放在编辑器中的文件不会立马进入Tomcat项目路径
        Tomcat中可以添加虚拟路径 来简化代码
        例如 原路径: /user/local/project/myProject/images
        在页面中访问的话 写起来比较麻烦
        我们可以配置虚拟路径
        /user/local/project/myProject = > myProject
        最终通过 myProject/images 来访问
        2.也可以使用相对于classpath的路径

上传步骤

页面上提交表单时 设置input的type为file

<img alt="头像" src="/images/${student.s_image }" width="200px" height="100px"/></td>
<input type="file" name="photo">

form表单中的enctype为multipart/form-data

enctype="multipart/form-data"
表示不对提交的数据进行任何的编码

接收文件的参数类型 设置为MultipartFile

@RequestMapping("updateStudent.action")
public String updateStudent(Student stu,MultipartFile photo) throws IllegalStateException, IOException {

}

配置文件中 配置一个文件解析器

<bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置最大上传大小 -->
    <property name="maxUploadSize" value="5000000"></property>
</bean>

将收到的文件 存储至指定的路径下

// 将收到的文件搞到硬盘上去
// 随机一个文件名 32长度的字符串
String fileName = UUID.randomUUID().toString();
// 获取后缀名   getOriginalFilename() 整个原始文件名
String extension = FilenameUtils.getExtension(photo.getOriginalFilename());

// 获取路径
File file = new File("/Users/lanou/Documents/images/"+fileName+"."+extension);
// 存到指定硬盘路径
photo.transferTo(file);

保存文件名数据到数据库

// 拼接文件名
String newFile = fileName + "." + extension;
stu.setS_image(newFile);
studentService.updateStudent(stu);
return "forward:getStudents.action";

SpringMVC 拦截器

SpringMVC拦截器与servlet中的过滤器是一个原理
如果同时存在 web中的filter与MVC中的过滤器,先执行web中的filter
因为SpringMVC拦截器是SpringMVC中的一个组件
只有请求以及交给了SpringMVC 拦截器才有可能执行

编写拦截器类 实现HandlerInterceptor

public class MyIntercept implements HandlerInterceptor{
    /*
     * 处理器执行前
     * 返回值用来控制是否要执行对应的控制器代码
     * 返回false不执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("处理器执行前1");
        return true;
    }
    // 处理执行后 没有异常才会执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("处理执行后1");
    }
    // 视图渲染完成后 也就是在jsp或html页面显示完成后执行
    // 无论处理器是否有异常都会执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("视图渲染完成后1");
    }

}

在配置文件中注册拦截器

<mvc:interceptors>
    // 通用拦截器 所有请求都拦截
    <bean class="com.lanou.intercept.MyIntercept"></bean>
    <!--拦截指定请求 如果配置了多个拦截器 执行顺序按照声明顺序-->

    <mvc:interceptor>
        // 只拦截/deleteStudents.action"请求
        <mvc:mapping path="/deleteStudents.action"/>
        <bean class="com.lanou.intercept.MyIntercept2"></bean>
    </mvc:interceptor>
</mvc:interceptors>

JSON交互

JSON用来接收更加复杂的数据,避免使用POJO创建很多不必要的实体类

1、请求时发送json格式的数据到后台
2、后台接口参数类型 Stirng  
        并添加@RequestBody
        @RequestBody表示不需要SpringMVC进行解析
            直接把接收的参数传到方法中
3、将收到的json字符串解析 并转换为实体对象
4、如果使用ajax请求name后台就不能返回一个页面 
    而应该返回普通字符串或是json格式字符串
5、前台收到json后进行解析并将数据展示到页面中
@RequestMapping(value="testAjaxRequest.action")
@ResponseBody 
public String ajaxRequest(@RequestBody String jsonString){
    // 将字符串转为json对象
    JSONObject jsonObject = JSON.parseObject(jsonString);
    // 将json对象转为实体类对象
    Student student = JSON.toJavaObject(jsonObject, Student.class);
    System.out.println(student);

    // 将集合转换为json格式字符串
    List<Student> stus = studentService.getStudents();
    String jsonStr= JSON.toJSONString(stus);

    // 创建一个json对象
    JSONObject j = new JSONObject();
    // 添加键值对
    j.put("name", "张三");
    j.put("age", 18);
    j.put("code", 200);
    // 创建一个json数组
    JSONArray ja = new JSONArray();
    // 在数组中添加一个小json表示这个人有几辆车
    JSONObject car = new JSONObject();
    car.put("carName", "奔驰");
    ja.add(car);
    // 将数组加到大的json对象中
    j.put("cars", ja);
    //"{'name':'张三','age':20,'cars':[{'carName':'奔驰'}]}"

    return j.toJSONString();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值