java5.4SpringMVC

目录


【概述】

  • MVC是模型(Model)、视图(View)、控制器(Controller)

java5.4SpringMVC

  • springMVC是什么?
  1. Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。

  2. Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)

一 初识springMVC

1.1 第一个springMVC

1)新建一个Moudle,并添加web支持

2)导入springMVC依赖,配置打包

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*</include>
            </includes>
        </resource>
    </resources>
</build>

3)配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--1.注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4)配置springmvc-servlet.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <!--视图解析器:DispatcherServlet给他的ModelAndView-->
    <!--1.获取ModelAndView中的数据 2.解析ModelAndView名字 3.拼接视图名-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <!--前缀--><property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀--><property name="suffix" value=".jsp"/>
    </bean>
    <!--Handler-->
    <bean id="/hello" class="com.zheng.controller.HelloController"/>
</beans>

5)编写控制类HelloController

public class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //ModelAndView 模型和视图
        ModelAndView mv = new ModelAndView();
        String method=request.getParameter("method");
        //封装对象,放在ModelAndView中
        if (method.equals("aa123")){
            mv.addObject("msg","HelloSpringMVC");
        }else {
            mv.addObject("msg","other");
        }
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello"); //等价于: /WEB-INF/jsp/hello.jsp
        return mv;
    }
}

6)在WEB-INF下添加 /jsp/hello.jsp

<body>
    <h1>hello spring-MVC</h1>
    <h4>${msg}</h4>
</body>

可能遇到的问题:访问出现404

文件》项目结构》工作》查看是否确实 lib 包
java5.4SpringMVC

如果缺少 lib 包则手动加上,并添加依赖

java5.4SpringMVC

1.2 原理概述

java5.4SpringMVC

用户发送请求:http://localhost:8080/SpringMVC/hello

【根据url解析处理器】

  1. 处理url,如:域名http://localhost:8080、站名SpringMVC、控制器hello
  2. DS 调用处理器映射,根据 url 查找到 Handel(处理器)
  3. 将解析的控制器信息返回到 DS

【控制器具体操作】

  1. 处理器按照规则执行 Handel,查找控制器类(实现 Controller 的类)
  2. 具体的 Controller 执行
  3. Controller返回执行结果(ModelAndView)
  4. 将视图逻辑名或模型传递给 DS

【解析视图名,返回视图】

  1. 调用视图解析器来解析 HandlerAdapter 传递的逻辑名,拼接
  2. 将解析名返回给 DS
  3. DS根据视图名查找视图
  4. 将视图返回给用户

1.3 注解实现

0)准备工作

  • 类似于配置实现的方式,需要在项目结构中手动添加lib包
  • 配置pom.xml

2)配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--1.注册servlet-->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!-- 启动顺序,数字越小,启动越早 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--所有请求都会被springmvc拦截 -->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

3)添加配置文件 springmvc-servlet.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: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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 资源过滤:让Spring MVC不处理静态资源 -->
    <mvc:default-servlet-handler />
    <!--支持mvc注解驱动-->
    <mvc:annotation-driven />
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!-- 前缀 --><property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 --><property name="suffix" value=".jsp" />
    </bean>
    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.zheng.controller"/>
</beans>

4)编写一个控制类 HelloController.java

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/HelloController")//可选项
public class HelloController {
    @RequestMapping("")//实际访问地址 /HelloController
    public String sayHello0(Model model){
        //向模型中添加属性msg与值,可以在JSP页面中取出并渲染
        model.addAttribute("msg","hello SpringMVC 000");
        return "hello"; //WEB-INF/jsp/hello.jsp
    }
    @RequestMapping("/h1")//实际访问地址 /HelloController/h1
    public String sayHello1(Model model){
        model.addAttribute("msg","hello SpringMVC 111");
        return "hello";
    }
}

归结起来就是四个东西。

  • @Controller注解类型用于声明Spring类的实例是一个控制器,并使用扫描机制来找到应用程序中所有基于注解的控制器类
  • @RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上
    • @PostMapping只能接收Post方式的请求
    • @GetMapping只能接收Get方式的请求
  • Model
  • return 返回一个视图名,通过视图解析器会自动拼接

5)在WEB-INF下添加 /jsp/hello.jsp 略

二 RestFul 风格

概念:

  • RestFul就是一个资源定位及资源操作的风格。
  • 不是标准也不是,只是一种风格。
  • 基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

2.1 @PathVariable

@PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量上

  • 原来url格式:xxx/add?a=1&b=2
  • RestFul格式:xxx/add2/1/2
@Controller
@RequestMapping("/count")
public class Count {
    //http://localhost:8080/mvc04/count/add?a=1&b=2
    @RequestMapping("/add")
    public String add(int a, int b, Model m){
        int res = a+b;
        m.addAttribute("msg","计算结果:"+res);
        return "hello";
    }
    //http://localhost:8080/mvc04/count/add2/1/2
    @RequestMapping("/add2/{a}/{b}")
    public String add2(@PathVariable int a,@PathVariable int b, Model m){
        int res = a+b;
        m.addAttribute("msg","计算结果:"+res);
        return "hello";
    }
}

2.2 小结

Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE

所有的地址栏请求默认都会是 HTTP GET 类型

方法级别的注解变体有如下几个

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping 等等…

特点:简洁、高效、安全

三 转发重定向和数据处理

3.1 ServletAPI

@RequestMapping("/servletAPI")
public void text(HttpServletRequest req, HttpServletResponse resp){
    try {
        System.out.println("session:"+req.getSession().getId());
        resp.getWriter().println("hello SrpingMVC servletAPI");
    } catch (IOException e) {
        System.out.println(e);
    }
}

可直接设置形参获取输入输出数据,可用以控制转发和重定向

3.2 springMVC实现

  • 转发不改变地址栏,重定向地址栏会变化
  • 添加redirect:关键字,可实现重定向,会跳过视图解析器
//转发 http://localhost:8080/mvc04/count/add?a=1&b=2
@RequestMapping("/add")
public String add(int a, int b, Model m){
    int res = a+b;
    m.addAttribute("msg","计算结果:"+res);
    return "hello";
}
//重定向
@RequestMapping("/sub")
public String sub(){
    return "redirect:/index.jsp";
}

3.3 处理接收数据

//接收普通参数  localhost:8080/mvc04/user/d1?username=zheng
@RequestMapping("/d1")
public String data01(@RequestParam("username") String name, Model m){
    System.out.println("获取前端传递参数:"+name);
    m.addAttribute("msg","name="+name);
    return "hello";
}

//接收对象参数  localhost:8080/mvc04/user/d2?name=zheng&age=18&id=001
@RequestMapping("/d2")
public String data02(User user, Model m){
    System.out.println("获取前端传递参数:"+user.toString());
    m.addAttribute("msg","name="+user);
    return "hello";
}

说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。

如:

输入:localhost:8080/mvc04/user/d2?name=zheng&age=18

输出:User{id=‘null’, name=‘zheng’, age=18}

3.4 乱码问题

使用pos提交数据时,提交中文会产生乱码

配置文件 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>

四 JOSN

json是一种轻量级的数据交换格式,采用文本格式来存储和表示数据,其实就是java中的字符串。

JavaScript 实现 JSON 和字符串的转换

字符串转JSON:

var obj = JSON.parse('{"a": "Hello", "b": "World"}');
//结果是 {a: 'Hello', b: 'World'}

JSON转字符串:

var json = JSON.stringify({a: 'Hello', b: 'World'});
//结果是 '{"a": "Hello", "b": "World"}'

4.1 jackson

【实现】

导包:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>
  • 将返回的信息封装成对象,再将对象转变成 JSON 格式
  • @ResponseBody:阻止视图解析器,返回一个字符串
@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
@ResponseBody
public String json1(Model m) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    User u = new User("小郑同学", "001", 18);
    //将对象转为JSON
    String s = mapper.writeValueAsString(u);
    return s;
}

注:RequestMapping 中加上 produces = “application/json;charset=utf-8” 是手动解决乱码问题。统一配置后可不加!

【乱码统一解决】

springmvc-servlet.xml

<mvc:annotation-driven>
    <!-- JSON乱码问题配置 -->
    <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>

【拓展】

  • @RestController:代替Controller,表示该类下的方法都阻止视图解析器,返回字符串
@RestController
@RequestMapping("/json")
public class UserCon {
    @RequestMapping(value = "/j1")
    public String json1(Model m) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        User u = new User("小郑同学", "001", 18);
        //将对象转为JSON
        String s = mapper.writeValueAsString(u);
        return s;
    }
}
  • 时间戳自定义时间格式输出
@RequestMapping("/j3")
public String json3() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    //不使用时间戳格式
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
    //自定义格式,并使用
    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    Date date = new Date();
    return mapper.writeValueAsString(date);
}
  • 封装工具类
public class JsonUtils {
    //默认开启时间戳格式转换 getJson(obj);
    public static String getJson(Object o){
        return getJson(o,"yyyy-MM-dd HH:mm:ss",true);
    }
    //自定义时间格式 getJson(obj,"MM-dd HH:mm:ss");
    public static String getJson(Object o,String diyData){
        return getJson(o,diyData,true);
    }
    //关闭时间戳 getJson(obj,false);
    public static String getJson(Object o,Boolean b){
        if (b){
            return getJson(o,"yyyy-MM-dd HH:mm:ss",true);
        }else{
            return getJson(o,"",false);
        }
    }
    //重写方法
    public static String getJson(Object o,String diyData,Boolean b){
        ObjectMapper mapper = new ObjectMapper();
        if(b){
            //不使用时间戳格式
            mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
            //自定义格式,并使用
            mapper.setDateFormat(new SimpleDateFormat(diyData));
        }
        try {
            return mapper.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

4.2 Fastjson

导包:

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>

使用

System.out.println("*******Java对象 转 JSON字符串*******");
String str1 = JSON.toJSONString(list);

System.out.println("\n****** JSON字符串 转 Java对象*******");
User jp_user1=JSON.parseObject(str2,User.class);

System.out.println("\n****** Java对象 转 JSON对象 ******");
JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);

System.out.println("\n****** JSON对象 转 Java对象 ******");
User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
上一篇:300行代码手写SpringMVC


下一篇:SpringMVC