springmvc学习

1、传统的javaweb,前端请求直接发送到servlet,在springmvc中设置了一个前端控制器Dispatcherservlet(本质也是servlet),前端控制器会转发请求到对应的controller中(某个指定业务模块的servlet)

2、例子

java 复制代码
package com.example.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class WebInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(MymvcConfig.class);//该类配置了需要扫描哪些包下的bean交给spring管理
        servletContext.addFilter("encodingFilter", new CharacterEncodingFilter("UTF-8",true));
        ctx.setServletContext(servletContext);
        //设置前端控制器DispatcherServlet
        ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
        //添加经过该控制器的所有路径地址/代表所有的亲求都经过该前端控制器
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}
java 复制代码
package com.example.controller;

import com.example.service.QuickService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class QuickStart {

    //直接输入service使用
    @Autowired
    private QuickService service;
    @RequestMapping("/show")
    public String show(){
        System.out.println("show running...."+service);
        //返回视图名称,即需要展示的jsp页面名称
        return "/show.jsp";
    }
}

3、springmvc关键组件

1)HandlerMapping(处理映射器):用于匹配请求url和对应controller方法

2)HandlerAdapter(处理适配器):适配不同类型的controller并调用该方法

3)ViewResolver(视图解析器):对返回的视图进行解析,一般不会用到,一般前后端开发都是通过json交互的

4、示例

java 复制代码
import com.example.domain.User;
import com.example.service.QuickService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/Quick")
public class QuickStart {

    //直接输入service使用
    @Autowired
    private QuickService service;
    @RequestMapping("/show")
    public String show(){
        System.out.println("show running...."+service);
        //返回视图名称,即需要展示的jsp页面名称
        return "/show.jsp";
    }

    @GetMapping("/show1")
    public String show1(String name,int age){
        System.out.println("show1..."+name+" "+age);
        return "/show1.jsp";
    }

    @GetMapping("/show2")
    public String show2(@RequestParam List<String> name){//接受list参数时,需要使用注释告诉spring,将参数封装为list
        System.out.println(name.get(0));
        return "/show1.jsp";
    }

    @GetMapping("/show3")
    public String show3(@RequestParam Map<String,Object> map){//接受map参数时,需要使用注释告诉spring,将参数封装为map
        map.forEach((k,v)->{
            System.out.println(k+"---"+v);
        });
        return "/show1.jsp";
    }

    @GetMapping("/show4")
    public String show4(@RequestParam("username") String name,int age){//入参名字和接收名字不一样时,用注释指定名字
        System.out.println("show4..."+name+" "+age);
        return "/show1.jsp";
    }

    @GetMapping("/show5")
    public String show5(@RequestParam(value = "username",required=true) String name,int age){//入参名字和接收名字不一样时,用注释指定名字,设置required是该参数必填
        System.out.println("show4..."+name+" "+age);
        return "/show1.jsp";
    }

    //http://localhost:8080/demo14_war_exploded/show6?name=zhangsan&age=9&hobbys=q&hobbys=u&birth=2023/9/9&address.city=tj&address.agea=44
    @GetMapping("/show6")
    public String show6(User user){//接收对象
        System.out.println(user);
        return "/show1.jsp";
    }

    @PostMapping ("/show7")
    public String show7(@RequestBody String user){//将请求体的数据封装到字符串里
        System.out.println(user);
        return "/show1.jsp";
    }

    @PostMapping ("/show8")
    public String show8(@RequestBody String body){//将请求体的数据封装到字符串里
        //使用jackson进行转换,间json格式的字符串转化为user对象
        ObjectMapper mapper = new ObjectMapper();
        try {
            User user = mapper.readValue(body,User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return "/show1.jsp";
    }

    @PostMapping ("/show9")
    public String show9(@RequestBody User user){//将请求体的数据封装到字符串里
        System.out.println(user);
        return "/show1.jsp";
    }

    @GetMapping ("/show10/{id}/{xxx}")//refu风格的提交方式
    public String show10(@PathVariable("id") int id,@PathVariable("xxx") String name){
        System.out.println(id);
        System.out.println(name);
        return "/show1.jsp";
    }

    @PostMapping("/show11")
    public String show11(@RequestBody MultipartFile myfile) throws IOException {
        System.out.println(myfile);
        //获得当前文件的输入流
        InputStream inputStream = myfile.getInputStream();
        //获得上传文件的输出流
        OutputStream outputStream = new FileOutputStream("D:\\"+myfile.getOriginalFilename());
        //文件拷贝
        IOUtils.copy(inputStream,outputStream);
        //关闭流资源
        inputStream.close();
        outputStream.close();
        return "/show1.jsp";
    }
    @GetMapping ("/show12")//获取指定头信息
    public String show12(@RequestHeader("Accept-Encoding") String headervalue){
        System.out.println(headervalue);
        return "/show1.jsp";
    }
    @GetMapping ("/show13")//获取所有头信息
    public String show13(@RequestHeader Map<String,String> map){
        map.forEach((k,v)->{
            System.out.println(k+":"+v);
        });
        return "/show1.jsp";
    }
    @GetMapping ("/show14")//获取所有头信息
    public String show14(@CookieValue("JSESSIONID") String jsessionid){
        System.out.println(jsessionid);
        return "/show1.jsp";
    }

    @GetMapping ("/show15")//间信息存入request域中
    public String show15(HttpServletRequest request){
        //向request域中存数据
        request.setAttribute("name","name");
        return "/show16";
    }

    @GetMapping ("/show16")//间信息存入request域中
    public String show16(@RequestAttribute("name") String name){
        //从request域中取出值
        System.out.println(name);
        return "/show1.jsp";
    }

    @GetMapping ("/show17")//获取request和response对象
    public String show17(HttpServletRequest request, HttpServletResponse response){
        System.out.println(request);
        System.out.println(response);
        return "/show1.jsp";
    }
}

5、客户端浏览器和服务器的同步数据交换方式,通过重定向redirect、转发forward来实现

6、客户端浏览器和服务器的异步数据交换方式:通过Ajax实现,通过创建XMLHttpRequest对象,可以向服务器发送请求和接收响应,使用open()方法初始化一个请求。这个方法接收三个参数:请求类型(如GET或POST)、请求的URL和一个布尔值表示是否异步,通过监听onreadystatechange事件等待请求的状态变化,比如请求状态变为200,表示请求成功得到了返回,使用send()方法发送请求,在回调函数中,根据请求的状态和响应内容进行处理。通常会检查readyState是否为4(请求完成)和status码是否表示成功

java 复制代码
@RestController
public class ResponseController {

    @RequestMapping("/res1")
    public String res1(){//重定向方式
        return "redirect:show.jsp";
    }

    @RequestMapping("/res2")
    public String res2(){//转发方式
        return "forward:show.jsp";
    }

    @RequestMapping("/res3")
    public ModelAndView res3(ModelAndView modelAndView){//转发方式带数据
        //封装模型数据和视图名
        //设置模型数据
        User user = new User();
        user.setName("zhangsan");
        user.setAge(19);
        modelAndView.addObject("user",user);
        //设置视图名称,再页面中展示模型数据
        modelAndView.setViewName("/show.jsp");
        return modelAndView;
    }

    @RequestMapping("/res4")
    @ResponseBody //告诉springmvc,返回值为响应体
    public String res4(){//直接展示字符串
        return "modelAndView";
    }

    @RequestMapping("/ajax//res5")
    @ResponseBody //告诉springmvc,返回值为响应体
    public String res5() throws JsonProcessingException {//异步方式返回数据
        User user = new User();
        user.setName("zhangsan");
        user.setAge(19);
        ObjectMapper mapper = new ObjectMapper();
        String jsonstr = mapper.writeValueAsString(user);
        return jsonstr;
    }

    @RequestMapping("/ajax//res6")
    //@ResponseBody //告诉springmvc,返回值为响应体,可以将返回值实体自动转换为json格式返回
    public User res6() throws JsonProcessingException {//异步方式返回数据
        User user = new User();
        user.setName("zhangsan");
        user.setAge(19);
        return user;
    }
}

7、springmvc拦截器:interceptor位于前端控制器dispatcherservlet后,拦截通过之后,才会到达对应的controller,主要拦截controller请求

1)prehandle:对请求进行拦截,返回true才能访问controller

2)posthandle:在执行controller方法执行之后执行,比如对其返回的视图进行处理

3)aftercompletion:在视图渲染完毕之后,进行最后的处理,比如对请求中的异常进行处理

多个拦截器对象,执行顺序就是addInterceptors的顺序,如果先后addInterceptors interceptor1和interceptor2,内部方法执行顺序prehandle1,prehandle2,posthandle2,posthandle1,aftercompletion2,aftercompletion1,因为内部执行时,循环遍历的顺序不一样,prehandle从前往后,posthandle从后往前,aftercompletion从后往前,如果interceptor2返回false,那么直接跳到aftercompletion1,因为两个拦截器有一个返回false,则无法到达controllor,posthandle都不执行

java 复制代码
@Configuration
@EnableWebMvc
@ComponentScan("com.example")
public class MymvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/page/*")
                .addResourceLocations("classpath:/static/");
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new Myinterceptor())
                .addPathPatterns("/**");
    }
}
java 复制代码
@Component
public class Myinterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle执行");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle执行");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion执行");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

8、前端控制器

1)DispatcherServlet是springmvc的入口,本质是一个servlet,它在初始化时,获得了一个springmvc的ApplicationContext容器,并向容器中注册springmvc的九大组件

java 复制代码
protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);//文件处理器
		initLocaleResolver(context);
		initThemeResolver(context);
		initHandlerMappings(context);//处理器映射器
		initHandlerAdapters(context);//处理器适配器
		initHandlerExceptionResolvers(context);
		initRequestToViewNameTranslator(context);
		initViewResolvers(context);//视图解析器
		initFlashMapManager(context);
	}
相关推荐
啊阿狸不会拉杆1 小时前
《计算机视觉:模型、学习和推理》第 2 章-概率概述
人工智能·python·学习·算法·机器学习·计算机视觉·ai
憧憬成为原神糕手1 小时前
音视频学习一
学习·音视频·视频编解码
Hello.Reader1 小时前
Flink State Backend 选型、配置、RocksDB 调优、ForSt 与 Changelog 一次讲透
java·网络·数据库
cqbzcsq2 小时前
MC Forge1.20.1 mod开发学习笔记(个人向)
笔记·学习·mod·mc·forge
人道领域2 小时前
Maven多环境配置实战指南
java·数据库·spring
蒸蒸yyyyzwd2 小时前
cpp学习笔记
笔记·学习
倚肆2 小时前
WebSocket 完整教程:从安装到实战
java·websocket
时艰.2 小时前
订单系统分库分表方案设计与实现
java
亓才孓2 小时前
[SpringBoot]@SpringBootTest标签作用
java·spring boot·log4j