• springMVC的学习【中】


    前言

    作为一个计算机专业的人,学习,记笔记,领悟是一个必经的过程!
    没有鲜花、掌声,但是我还是要写下自己学习的东西
    同样的知识,不一样精彩……

    五 结果跳转方式

    5.1 ModelAndView

    • 设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面
    • 页面 : {视图解析器前缀} + viewName +{视图解析器后缀}
    
    <bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    id="internalResourceViewResolver">
    
    <property name="prefix" value="/WEB-INF/jsp/" />
    
    <property name="suffix" value=".jsp" />
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 对应的controller类
    public class ControllerTest1 implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
    HttpServletResponse httpServletResponse) throws Exception {
    		//返回一个模型视图对象
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("msg","ControllerTest1");
    		mv.setViewName("test");
    		return mv;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.2 ServletAPI

    • 通过设置ServletAPI , 不需要视图解析器 .
      1. 通过HttpServletResponse进行输出
      2. 通过HttpServletResponse实现重定向
      3. 通过HttpServletResponse实现转发
    @Controller
    public class ResultGo {
    	@RequestMapping("/result/t1")
    	public void test1(HttpServletRequest req, HttpServletResponse rsp)
    	throws IOException {
    	rsp.getWriter().println("Hello,Spring BY servlet API");
    }
    @RequestMapping("/result/t2")
    public void test2(HttpServletRequest req, HttpServletResponse rsp)
    	throws IOException {
    	rsp.sendRedirect("/index.jsp");
    }
    @RequestMapping("/result/t3")
    public void test3(HttpServletRequest req, HttpServletResponse rsp)
    throws Exception {
    	//转发
    	req.setAttribute("msg","/result/t3");
    	req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5.3 SpringMV【重点】

    • 通过SpringMVC来实现转发和重定向 - 无需视图解析器;
    @Controller
    public class ResultSpringMVC {
    
    	@RequestMapping("/rsm/t1")
    	public String test1(){
    		//转发
    		return "/index.jsp";
    	}
    	
    	@RequestMapping("/rsm/t2")
    	public String test2(){
    		//转发二
    		return "forward:/index.jsp";
    	}
    	
    	@RequestMapping("/rsm/t3")
    	public String test3(){
    		//重定向
    		return "redirect:/index.jsp";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 通过SpringMVC来实现转发和重定向 - 有视图解析器;
    • 重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方嘛 , 所以注意路径问题.
    @Controller
    public class ResultSpringMVC2 {
    
    	@RequestMapping("/rsm2/t1")
    	public String test1(){
    		//视图跳转
    		return "test";
    	}
    	
    	@RequestMapping("/rsm2/t2")
    	public String test2(){
    		//重定向
    		return "redirect:/index.jsp";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    六 数据处理

    6.1 处理提交数据

    提交的域名称和处理方法的参数名一致

    1. 提交数据 : http://localhost:8080/hello?name=kuangshen
    • 处理方法:
    @RequestMapping("/hello")
    public String hello(String name){
    	System.out.println(name);
    	return "hello";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 提交的域名称和处理方法的参数名不一致
    • 提交数据 : http://localhost:8080/hello?username=kuangshen
    • 处理方法 :
    //@RequestParam("username") : username提交的域的名称 .
    @RequestMapping("/hello")
    	public String hello(@RequestParam("username") String name){
    	System.out.println(name);
    	return "hello";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 提交的是一个对象
    • 要求提交的表单域和对象的属性名一致 , 参数使用对象即可

      1. 实体类
      public class User {
      	private int id;
      	private String name;
      	private int age;
      	//构造
      	//get/set
      	//tostring()
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      1. 提交数据 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

      2. 处理方法

      @RequestMapping("/user")
      public String user(User user){
      	System.out.println(user);
      	return "hello";
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

    6.2 数据显示到前端

    方式一:通过ModelMap

    @RequestMapping("/hello")
    public String hello(@RequestParam("username") String name, ModelMap model){
    	//封装要显示到视图中的数据
    	//相当于req.setAttribute("name",name);
    	model.addAttribute("name",name);
    	System.out.println(name);
    	return "hello";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方式二:通过Model

    @RequestMapping("/ct2/hello")
    public String hello(@RequestParam("username") String name, Model model){
    	//封装要显示到视图中的数据
    	//相当于req.setAttribute("name",name);
    	model.addAttribute("msg",name);
    	System.out.println(name);
    	return "test";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方式三:通过ModelAndView

    public class ControllerTest1 implements Controller {
    	public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
    	HttpServletResponse httpServletResponse) throws Exception {
    		//返回一个模型视图对象
    		ModelAndView mv = new ModelAndView();
    		mv.addObject("msg","ControllerTest1");
    		mv.setViewName("test");
    		return mv;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6.3 对比

    Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解。
    ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性。
    ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

    6.4 乱码问题

    <filter>
    	<filter-name>encodingfilter-name>
    	<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    	<init-param>
    		<param-name>encodingparam-name>
    		<param-value>utf-8param-value>
    	init-param>
    filter>
    <filter-mapping>
    	<filter-name>encodingfilter-name>
    	<url-pattern>/*url-pattern>
    filter-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 有些极端情况下.这个过滤器对get的支持不好
    1. 修改tomcat配置文件 : 设置编码!
    <Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />
    
    • 1
    • 2
    • 3

    终极自定义过滤器

    package com.yang.filter;
    
    /**
     * @author 缘友一世
     * @date 2022/7/30-22:03
     */
    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;
    /**
     * 解决get和post请求 全部乱码的过滤器
     */
    public class GenericEncodingFilter implements Filter {
        public void destroy() {
        }
        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);
        }
        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;
        }
    }
    
    
    • 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
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    解决IDEA终端中文乱码

    在这里插入图片描述

     <init-param>
                <param-name>fileEncodingparam-name>
                <param-value>UTF-8param-value>
            init-param>
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    在这里插入图片描述

    七 Json

    什么是JSON?

    • JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广泛。
    • 采用完全独立于编程语言的文本格式来存储和表示数据。
    • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
    • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
    • 在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例
      如字符串、数字、对象、数组等。看看他的要求和语法格式:
      • 对象表示为键值对,数据由逗号分隔
      • 花括号保存对象
      • 方括号保存数组
    • JSON 键值对是用来保存 JavaScript 对象的一种方式
    {"name": "QinJiang"}
    {"age": "3"}
    {"sex": "男"}
    
    • 1
    • 2
    • 3
    • JSON 和 JavaScript 对象的关系

    JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。

    var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
    var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
    
    • 1
    • 2
    • JSON 和 JavaScript 对象互转
      • 要实现从JSON字符串转换为JavaScript 对象,使用 JSON.parse() 方法
      var obj = JSON.parse('{"a": "Hello", "b": "World"}');
      //结果是 {a: 'Hello', b: 'World'}
      
      • 1
      • 2
      • 要实现从JavaScript 对象转换为JSON字符串,使用 JSON.stringify() 方法
      var json = JSON.stringify({a: 'Hello', b: 'World'});
      //结果是 '{"a": "Hello", "b": "World"}'
      
      • 1
      • 2
    • 栗子
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>JSON_秦疆</title>
    </head>
    <body>
    	<script type="text/javascript">
    	//编写一个js的对象
    	var user = {
    		name:"秦疆",
    		age:3,
    		sex:"男"
    	};
    	
    	//将js对象转换成json字符串
    	var str = JSON.stringify(user);
    	console.log(str);
    	
    	//将json字符串转换为js对象
    	var user2 = JSON.parse(str);
    	console.log(user2.age,user2.name,user2.sex);
    	
    	</script>
    </body>
    </html>
    
    • 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

    8.2 Controller返回JSON数据

    • Jackson应该是目前比较好的json解析工具
    • 当然工具不止这一个,比如还有阿里巴巴的 fastjson 等等
    
            <dependency>
                <groupId>com.fasterxml.jackson.coregroupId>
                <artifactId>jackson-databindartifactId>
                <version>2.13.3version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    8.3 代码优化

    • 乱码统一解决,如果项目中有许多请求则每一个都要添加,可以通过Spring配置统一指定
    <!--JSON乱码问题配置-->
        <mvc:annotation-driven>
            <mvc:message-converters register-defaults="true">
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <constructor-arg value="UTF-8"/>
                </bean>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                        <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                            <property name="failOnEmptyBeans" value="false"/>
                        </bean>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 返回json字符串统一解决
      • 在类上直接使用 @RestController ,里面所有的方法都只会返回 json 字符串了,不用再每一个都添加@ResponseBody !
      • 在前后端分离开发中,一般都使用 @RestController ,十分便捷
    @RestController
    public class UserController {
    	//produces:指定响应体返回类型和编码
    	@RequestMapping(value = "/json1")
    	public String json1() throws JsonProcessingException {
    		//创建一个jackson的对象映射器,用来解析数据
    		ObjectMapper mapper = new ObjectMapper();
    		//创建一个对象
    		User user = new User("秦疆1号", 3, "男");
    		//将我们的对象解析成为json格式
    		String str = mapper.writeValueAsString(user);
    		//由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
    		return str;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    8.4 抽取为工具类

    • 如果要经常使用的话,这样是比较麻烦的,我们可以将这些代码封装到一个工具类中
    package com.yang.utils;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import java.text.SimpleDateFormat;
    
    /**
     * @author 缘友一世
     * @date 2022/7/31-11:18
     */
    public class JsonUtils {
    
        public static String getJson(Object object) {
            return getJson(object,"yyy-MM-dd HH:mm:ss");
        }
    
        public static String getJson(Object object,String dateFormat) {
            //jackson, objectMapper
            ObjectMapper mapper = new ObjectMapper();
            //时间的默认格式为时间戳,不使用时间戳的方式
            mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
    
            //自定义日期的格式
            SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
            mapper.setDateFormat(sdf);
    
            try {
                return mapper.writeValueAsString(object);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
    • 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
     @RequestMapping("/j5")
        @ResponseBody//直接放回一个字符串,不会走视图解析器
        public String json5() {
            Date date = new Date();
            //值传递一个参数时,默认时间格式:return JsonUtils.getJson(date);
            return JsonUtils.getJson(date,"yyy-MM-dd HH:mm:ss");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    8.5 FastJson

    • fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转
      换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。实现json的转换方法
      很多,最后的实现结果都是一样的。
    
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>fastjsonartifactId>
                <version>2.0.10version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 测试
    public class fastJsonDemo {
        public static void main(String[] args) {
    //创建一个对象
            User user1 = new User("秦疆1号", 3, "男");
            User user2 = new User("秦疆2号", 3, "男");
            User user3 = new User("秦疆3号", 3, "男");
            User user4 = new User("秦疆4号", 3, "男");
            List<User> list = new ArrayList<User>();
            list.add(user1);
            list.add(user2);
            list.add(user3);
            list.add(user4);
            System.out.println("*******Java对象 转 JSON字符串*******");
            String str1 = JSON.toJSONString(list);
            System.out.println("JSON.toJSONString(list)==>"+str1);
            String str2 = JSON.toJSONString(user1);
            System.out.println("JSON.toJSONString(user1)==>"+str2);
            System.out.println("\n****** JSON字符串 转 Java对象*******");
            User jp_user1=JSON.parseObject(str2,User.class);
            System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);
            System.out.println("\n****** Java对象 转 JSON对象 ******");
            JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
            System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));
            System.out.println("\n****** JSON对象 转 Java对象 ******");
            User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
            System.out.println("JSON.toJavaObject(jsonObject1,User.class)==>"+to_java_user);
        }
    }
    
    • 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
  • 相关阅读:
    node_exporter prometheus grafana 系统监控
    小程序提交表单之后,清除表单form
    Mybatis-plus中更新date类型数据遇到的坑
    《MySQL实战45讲》——学习笔记18 “索引失效、函数/隐式转换“【建议收藏】
    数据研发“新人”如何快速落地?
    lintcode 1840 · 矩阵还原【中等 vip 二维前缀和数组】
    国际版阿里云/腾讯云免开户:云存储服务:云存储服务能够让你随时随地拜访和同享文件
    BSA-PEI,牛血清白蛋白-聚乙烯亚胺,BSA-聚乙烯亚胺的保存
    Android_Monkey_测试执行策略及标准
    CSDN博客中插入公式的对齐操作
  • 原文地址:https://blog.csdn.net/yang2330648064/article/details/126149149