SpringMVC3----@Controller注解、RestFul风格的讲解和应用、SpringMVC的接受请求参数、网页跳转方式和数据回显、乱码问题

7 Controller类的写法

7.1 继承Controller接口
  • 在自己写的Conrtoller类中继承Controller接口,
  • 实现接口方法,
  • 返回填写好数据信息和页面信息的ModelAndView对象。
  • 在去容器中注册bean,id要加"/"符号

相关的注解(一样的作用):
@Component 组件
@Service service层
@Controller controller层
@Repository dao层

这些注解表示该类会被Spring接管,被这个注解的类中的所有方法,如果返回值是String并且有具体页面可以跳转的,那么就会被视图解析器解析。
四个注解不能混用,对应的类要用对应的注解,否则解析找不到资源。

@Controller注解类型用于声明Spring的实例是一个控制器。

Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能够在应用程序中找到注解,需要在配置文件中声明组件扫描

<!-- 自动扫描指定的包,包下所有注解类都交给IOC容器来管理 -->
<context:component-scan base-package="com.swrici.controller"/>
7.2 一个简单通过@Controller注解实现的程序。
  1. 开启注解扫描
<?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">
    <!-- 自动扫描指定的包,包下所有注解类都交给IOC容器来管理 -->
    <context:component-scan base-package="com.swrici.controller"/>
    <!--<mvc:default-servlet-handler/>-->
    <!--<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>
</beans>
  1. 增加一个MyController类,使用注解实现。
@Controller	//@Controller注解的类会自动添加到Spring中的上下文中
public class MyController2 {
	//映射访问路径 ,可作用于方法
    @RequestMapping("/h2")
    public String test1(Model model){
		//SpringMVC会自动实例化一个Model对象用于向视图中传值。
        model.addAttribute("msg","hello,My friend!");
		//返回视图位置
        return "hello";//WEB-INF/jsp/hello.jsp
    }
}

  1. WEB-INF目录下有jsp文件夹下有hello.jsp页面。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

  1. 运行Tomcat测试。
  2. 运行结果。
    在这里插入图片描述
    如果再在Controller类中增添新的方法并且指向通过页面,并传递的值不同的话,我们可以发现,页面的结果是不一样的,得出结论就是视图是可以复用的,而控制器和视图之间是弱耦合关系。
7.3 @RequestMapping
  • @RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法,可以用于类或方法上,用于类上表示类的所有响应请求的方法都是以该父地址为父路径。
  • @RequestMapping同时注解类和方法,如下
    代码:
@Controller
@RequestMapping("/h2")
public class MyController3 {
    @RequestMapping("/c3test1")
    public String test1(Model model){
        model.addAttribute("msg","MyController3.test1()");
        return "hello";
    }
}

例如:
在这里插入图片描述

8 RestFul风格

8.1 RestFul风格概念

RestFul风格就是一个资源定位和资源操作的风格,不是标准也不是协议,基于这个风格设计的软件可以更加简洁,更有层次感,更易于实现缓存机制。(url参数用斜线连接)

  • 资源:互联网上所有的事物都可以抽象为资源。
  • 资源操作:使用POST,GET,PUT,DELETE,使用不同方法对资源进行操作。

传统方式操作资源:

通过不同的参数实现不同的效果!方式单一,post和get.

  • http://127.0.0.1/item/queryItem.action?id=1 查询GET
  • http://127.0.0.1/item/saveItem.action?id=1 新增POST
  • http://127.0.0.1/item/updateItem.action?id=1 修改POST
  • http://127.0.0.1/item/deleteItem.action?id=1 删除GET或POST

使用RestFul风格操作资源:

可以通过不同的请求方式来实现不同的效果!如下,请求地址一样,但是功能可以不同。

  • http://127.0.0.1/item/1 查询 ,GET
  • http://127.0.0.1/item 新增,POST
  • http://127.0.0.1/item 更新,PUT
  • http://127.0.0.1/item/1 删除,DELETE
8.2 RestFul风格代码实例:
  • 新建一个Controller类
@Controller
public class RestFulController {
    //传统风格:http://localhost:8976/add?a=1&&b=3
    //RestFul:http://localhost:8976/add/2/5
    //映射访问路径 value映射访问路径,method确定访问方式
    @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
    public  String  test1(@PathVariable int a,@PathVariable int b, Model model){
        int res = a+b;
        //SpringMVC会自动实例化一个Model对象用于向视图中传值
        model.addAttribute("msg",res);
        //返回视图位置
        return "hello";
    }
}

在SpringMVC中可以通过 @PathVariable 注解,绑定一个url中的变量,该变量可以在@RequestMapping中使用。当映射路径中使用了@PathVariable注解的变量时,传统风格的传参方式会找不到资源,并且如果不带参也找不到资源,参数类型不同也会找不到资源。

使用路径变量的好处(@PathVariable),

  • 使路径更加简洁。
  • 通过参数更加方便,框架会自动进行类型转换。
  • 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法

传参方式

  • 传参方式可以在@RequestMapping中调用method=RequestMapping.[DELETE]|[PUT]|[POST]|GET]等设置具体的传参方式。
  • 传参方式也可以一开始就调用对应的注解进行设置。
    例如:@GetMapping、@PostMapping、@PatchMapping等等,都是修改前面单词即可。

405–接受方法(传参方式)不对,目标资源不支持。
小黄鸭调试法:解释一遍自己的代码,会突然发现代码的问题在哪里。我也需要一只小黄鸭!

9 SpringMVC:结果跳转方式

9.1 ModelAndView

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>

对应的Controller类

public class MyController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //返回一个模型视图对象
        ModelAndView modelAndView = new ModelAndView();
		//在对象中添加具体的K-V信息
        modelAndView.addObject("msg","GGBoy");
		//对象的ViewName设置
        modelAndView.setViewName("hello");
        return modelAndView;
    }
}
9.2 ServletAPI

通过设置ServletAPI,不需要视图解析器

  1. 通过HttpServletResponse进行输出。
  2. 通过HttpServletResponse进行重定向。
  3. 通过HttpServletRequest实现转发。
@Controller
public class ModelTest1 {
    //控制台打印SessionId,表示我们可以拿到request和response
    @RequestMapping("/ModelTest1/test1()")
    public String test1(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        System.out.println(session.getId());
        return "hello";
    }

    //使用response输出,在前端打印出信息
    @RequestMapping("/ModelTest1/test2()")
    public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().println("Hello,Spring BY Servlet API.");
    }

    //转发,使用Response跳转页面,
    @RequestMapping("/ModelTest1/test3()")
    public void test3(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendRedirect("/index.jsp");
    }

    //重定向,使用Request跳转页面,
    @RequestMapping("/ModelTest1/test4()")
    public void test4(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        request.setAttribute("msg","/ModelTest1/test4()");
        request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request,response);
    }
}
9.3 SpringMVC
9.3.1 SpringMVC无视图解析器,进行重定向和转发
@RequestMapping("m1/t5")
public String test5(Model model){
    model.addAttribute("msg","我来负责证明你不用视图解析器进行结果跳转!");
    //默认的return路径,url没有变,调用了转发的方式
    return  "/WEB-INF/jsp/hello.jsp";
}

@RequestMapping("m1/t6")
public String test6(Model model){
    model.addAttribute("msg","我来负责证明你不用视图解析器进行结果跳转!");
    //url没有变,调用了转发的方式
    return  "forward:/WEB-INF/jsp/hello.jsp";
}

@RequestMapping("m1/t7")
public String test7(Model model){
    model.addAttribute("msg","我来负责证明你不用视图解析器进行结果跳转!");
    //url改变,调用了重定向的方式
    return  "redirect:/index.jsp";
}
9.3.2 有视图解析器的时候
@RequestMapping("m1/t8")
public String test8(Model model){
    //url改变,调用了重定向的方式
    return  "redirect:/index.jsp";
}

@RequestMapping("m1/t9")
public String test9(Model model){
    model.addAttribute("msg","我来负责证明你用视图解析器进行结果跳转!");
    //url不变,调用了转发的方式
    return  "hello";
}

10 接收请求参数和数据回显

10.1 接受请求参数
10.1.1 接收单个参数请求
//1.前端传递的是单个参数
@GetMapping("/t1")
public String test1(String name, Model model){
    //1.接受前端参数
    System.out.println("接受到前端参数");
    //2.将返回结果传递给前端
    model.addAttribute("msg","接受到前端参数为:"+name);
    //3.视图跳转
    return "hello";
}

访问Url:http://localhost:8080/user/t2?name=swrici

10.1.2设置接受请求参数的别名

在方法参数前面使用 @RequestParam(“别名”) 注解。

//1.前端传递的是单个参数
@GetMapping("/t1")
public String test1(@RequestParam("userName") String name, Model model){
    //1.接受前端参数
    System.out.println("接受到前端参数");
    //2.将返回结果传递给前端
    model.addAttribute("msg","接受到前端参数为:"+name);
    //3.视图跳转
    return "hello";
}

访问Url:http://localhost:8080/user/t2?userName=swrici

10.1.3 对象传参
//2.前端传递的是一个对象
    /*
        使用对象接收多个数据的时候
        1.当数据名字和对象中的属性名一致的话,
          则赋值给对象中的属性,如果匹配不到,
          则对象属性为不赋值的默认值
     */
@GetMapping("/t2")
public String test2(User user){
    System.out.println(user);
    return "hello";
}

urlhttp://localhost:8976/user/t2?id=1&name=swrici&age=3

10.2 数据回显到前端
10.2.1 通过ModelAndView
//类实现Controller接口handleRequest()方法
//在该方法中通过返回ModelAndView对象来回显数据
public class MyController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //返回一个模型视图对象
        ModelAndView modelAndView = new ModelAndView();
		//设置模型中携带的数据
        modelAndView.addObject("msg","GGBoy");
		//设置视图的名字
        modelAndView.setViewName("hello");
        return modelAndView;
    }
}
10.2.2 通过ModelMap
@GetMapping("/t3")
public String test3(ModelMap modelMap){
    modelMap.addAttribute("msg","我是modelMap");
    return "hello";
}
10.2.3 通过Model
@GetMapping("/t4")
public String test4(Model model){
    model.addAttribute("msg","我是model");
    return "hello";
}
10.3 Model、ModelMap和ModelAndView

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

11 乱码问题解决方案

11.1 自编过滤器解决乱码
  1. 编写过滤器类
public class EnCodingFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    public void destroy() {

    }
}

  1. 去web.xml注册过滤器
 <filter>
     <filter-name>encoding</filter-name>
     <filter-class>com.swrici.filter.EnCodingFilter</filter-class>
 </filter>
 <filter-mapping>
     <filter-name>encoding</filter-name>
     <url-pattern>/</url-pattern>
 </filter-mapping>

这种自己编写过滤器的方法可以解决Get方式传参带来的影响,但无法解决Post方法乱码的影响。

11.2 SpringMVC自带的过滤器
<!--2.配置SpringMVC的乱码过滤器-->
    <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>

通过web.xml中配置SpringMVC过滤器就可以解决大部分的情况下的get和post请求乱码情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值