• SpringMVC


    处理提交出去的数据

    ModelAndView

    @RequestMapping("test3")
    public ModelAndView test3(ModelAndView modelAndView) {
        User user = new User(1212, "李四", "密码");
        modelAndView.addObject("user", user);
        modelAndView.setViewName("a");
        return modelAndView;
    }
    

    ModelMap

    @RequestMapping("test2")
    public String test2(ModelMap modelMap) {
        User user = new User(1212, "张飒", "密码");
        modelMap.addAttribute("user", user);
        return "a";
    }
    

    Model

    @RequestMapping("test4")
    public String test4(Model model) {
        User user = new User(1212, "王五", "密码");
        model.addAttribute("user", user);
        return "a";
    }
    

    区别

    • ModelAndView : 可以存储数据,也可以设置跳转的页面
    • ModelMap : 继承了LinkedMap,有更强的功能
    • Model : 只有几个方法,简单

    @ModelAttribute

    • 该注解可以使用在方法和方法参数上

    注释在方法上

    • 在同一个控制器中,注解了@ModelAttribute的方法实际上会在@RequestMapping方法之前被调用
    @Controller
    public class UserController {
        @RequestMapping("/test")
        public void update() {
            System.out.println("111111111");
        }
        @ModelAttribute
        public void getStudent1() {
            System.out.println("222222222");
        }
    }
    

    image-20210304171248814

    无返回值注释在方法上

    • 可以通过@ModelAttribute注释的方法较先执行的特性,使用Model对象设置参数
    • 在控制器跳转的页面中可以取得 Model 中设置的参数
    • 可以使用 @ModelAttribute 注释的方法来设置其他 @ReqeustMapping 方法的公用参数
    @Controller
    public class UserController {
        @RequestMapping("/test")
        public String test1() {
            return "hh";
        }
        @ModelAttribute
        public void test2(Model model) {
            model.addAttribute("ooo","HELLO");
        }
    }
    

    image-20210304171900233

    有返回值注释在方法上

    • 没有返回值的使用Model对象model.addAttribute(String key, Object value);来设置参数
    • 而有返回值的则需要直接返回参数即可,jsp使用${student}接收即可
    @Controller
    public class UserController {
        @RequestMapping("/test")
        public String update() {
            return "hh";
        }
        @ModelAttribute
        public Student getStudent1() {
            return new Student(1,"张飒",18);
        }
    }
    

    image-20210304173253975

    • 也可以给@ModelAttribute指定一个name,在jsp页面使用指定的name取值

    image-20210304173613929

    @ModelAttribute 和 @RequestMapping 注解在同一个方法上

    • 如果 @ModelAttribute 和 @RequestMapping 注解在同一个方法上,那么代表给这个请求单独设置 Model 参数
    • 此时返回的值是 Model 的参数值,而不是跳转的地址
    • 跳转的地址是根据请求的 url 自动转换而来的,就是@RequestMapping()中的参数

    image-20210304175105692

    @ResponseBody

    • 只能作用在方法和类上
    • @ResponseBody的作用其实是将java对象转为json格式的数据
    • 在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据
    • 一般用于ajax异步请求数据
    @RequestMapping("test1")
    @ResponseBody
    public String tets1(){
        return "OK";
    }
    @RequestMapping("test2")
    public @ResponseBody User test2(){
        return new User("陌路邑人","mlyr",new Date());
    }
    @RequestMapping("test3")
    @ResponseBody
    public List<User> test3(){
        User user = new User("???","1515",new Date());
        User user2 = new User("###","212",new Date());
        List<User> list = new ArrayList<>();
        list.add(user);
        list.add(user2);
        return list;
    }
    

    image-20210305120903511

    但是,有个问题,当对象有时间类型的时候,他会把Date类型的数据转换为时间戳传出去

    解决时间被转换为时间戳

    第一种方式:@JsonFormat

    • 在实体类上加上@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private String name;
        private String pwd;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date date;
    }
    
    • 但是他需要jackson-databind依赖

    • <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.12.1</version>
      </dependency>
      

    第二种方式:全局配置

    • 和第一种一样,都需要jackson-databind依赖
    <?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:mvc="http://www.springframework.org/schema/mvc"
           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/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <!--扫描指定包下加有注解的放入spring容器中-->
        <context:component-scan base-package="com.mlyr.k"/>
        <mvc:annotation-driven>
            <!--配置消息转换器器-->
            <mvc:message-converters>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                        <!--配置日期json转换-->
                        <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                            <property name="dateFormat">
                                <bean class="java.text.SimpleDateFormat">
                                    <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
                                </bean>
                            </property>
                        </bean>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        <mvc:default-servlet-handler/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    </beans>
    
    • 这种的还有一种写法,自定义消息转换器
    public class UserHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
        //当前的转换器支持转换的类
        @Override
        protected boolean supports(Class<?> clazz) {
            if (clazz == UserController.class) {
                return true;
            }
            return false;
        }
        //用于或取数据调用
        @Override
        protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
            return null;
        }
        //用于输出数据调用
        @Override
        protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
            //获取输出流
            OutputStream body = outputMessage.getBody();
            //配置日期转换器
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
            objectMapper.writeValue(body,obj);
        }
    }
    
    <?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:mvc="http://www.springframework.org/schema/mvc"
           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/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <context:component-scan base-package="com.mlyr.l"/>
        <mvc:annotation-driven>
            <!--配置消息转换器-->
            <mvc:message-converters register-defaults="true">
                <!--自定义的信息转换器-->
                <bean class="com.mlyr.l.UserHttpMessageConverter">
                    <!--转换器支持的格式-->
                    <property name="supportedMediaTypes" >
                        <list>
                            <value>application/json</value>
                        </list>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        <mvc:default-servlet-handler/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    
    </beans>
    

    乱码处理

    • 在web.xml中添加,字符编码
    <filter>
        <filter-name>encoding</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>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    • 大佬写的全局乱码解决
    package com.mlyr;
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.util.Map;
    
    /**
     * @Description:
     * @Author: 陌路邑人
     * @CreateTime: 2021/3/3
     * @Company:
     */
    public class GenericEncodingFilter implements Filter {
        @Override
        public void destroy() {
        }
        @Override
        public void doFilter(ServletRequest request, ServletResponse
                response, FilterChain chain) throws IOException, ServletException {
            //处理response的字符编码
            HttpServletResponse myResponse = (HttpServletResponse) response;
            myResponse.setContentType("text/html;charset=UTF-8");
            // 转型为与协议相关对象
            HttpServletRequest httpServletRequest = (HttpServletRequest)
                    request;
            // 对request包装增强
            HttpServletRequest myrequest = new
                    MyRequest(httpServletRequest);
            chain.doFilter(myrequest, response);
        }
        @Override
        public void init(FilterConfig filterConfig) throws
                ServletException {
        }
    }
    //自定义request对象,HttpServletRequest的包装类
    class MyRequest extends HttpServletRequestWrapper {
        private HttpServletRequest request;
        //是否编码的标记
        private boolean hasEncode;
    
        //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
        public MyRequest(HttpServletRequest request) {
            super(request);// super必须写
            this.request = request;
        }
    
        // 对需要增强方法 进行覆盖
        @Override
        public Map getParameterMap() {
            // 先获得请求方式
            String method = request.getMethod();
            if (method.equalsIgnoreCase("post")) {
                // post请求
                try {
                    // 处理post乱码
                    request.setCharacterEncoding("utf-8");
                    return request.getParameterMap();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            } else if (method.equalsIgnoreCase("get")) {
                // get请求
                Map<String, String[]> parameterMap =
                        request.getParameterMap();
                if (!hasEncode) { // 确保get手动编码逻辑只运行一次
                    for (String parameterName : parameterMap.keySet()) {
                        String[] values = parameterMap.get(parameterName);
                        if (values != null) {
                            for (int i = 0; i < values.length; i++) {
                                try {
                                    // 处理get乱码
                                    values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");
                                } catch (UnsupportedEncodingException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    hasEncode = true;
                }
                return parameterMap;
            }
            return super.getParameterMap();
        }
        //取一个值
        @Override
        public String getParameter(String name) {
            Map<String, String[]> parameterMap = getParameterMap();
            String[] values = parameterMap.get(name);
            if (values == null) {
                return null;
            }
            return values[0]; // 取回参数的第一个值
        }
    
        //取所有值
        @Override
        public String[] getParameterValues(String name) {
            Map<String, String[]> parameterMap = getParameterMap();
            String[] values = parameterMap.get(name);
            return values;
        }
    }
    
    
    • 在web.xml中配置过滤器即可
    <filter>
        <filter-name>myFiter</filter-name>
        <filter-class>com.mlyr.GenericEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myFiter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    不经风雨,怎见彩虹?
  • 相关阅读:
    洛谷P5113 Sabbat of the witch
    「学习笔记」洲阁筛
    【UNR #3】百鸽笼
    LOJ#6703. 小 Q 的序列
    python数组字符串还原为数组
    QGIS导入excel点数据
    QGIS统计面要素中包含的点要素数量
    gpd.read_file(),报错路径在系统文件中不存在
    QGIS平移要素
    QGIS多部件面转单部件面
  • 原文地址:https://www.cnblogs.com/MLYR/p/14487032.html
Copyright © 2020-2023  润新知