SpringMVC

目录

1.MVC执行流程 

五大组件:

执行流程:

2.Spring MVC 获取表单数据的几种方式

3.SpringMVC怎么样设定重定向和转发的?

4.如何解决POST请求中文乱码问题,GET的又如何处理呢?

5.SpringMvc是不是单例模式,如果是,有什么问题,怎么解决?

6.SpringMVC文件上传步骤:

7.SpringMVC常用的注解有哪些?

8. @Autowired 与 @Resource 的区别:

9.Spring MVC中的异常处理

10.Spring Boot 中如何解决跨域问题 ?

1.@CrossOrigin注解   

2.  GateWay网关解决


1.MVC执行流程 

8030ab6dc1554e6589dffe82403a9dbe.png

五大组件:

(1)前端控制器 DispatcherServlet(不需要程序员开发)

作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。

(2)处理器映射器 HandlerMapping(不需要程序员开发)

作用:根据请求的URL来查找Handler

(3)处理器适配器 HandlerAdapter

注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。

(4)处理器 Handler(需要程序员开发)

(5)视图解析器 ViewResolver(不需要程序员开发)

作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)

(6)视图 View(需要程序员开发jsp)

View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)

执行流程:

1、用户发送请求到前端控制器DispatcherServlet

2、DispatcherServlet收到请求调用处理映射器HandlerMapping

3、处理映射器根据请求url找到具体的处理器,生成处理器执行链HandlerExecutionChain(包含处理器对象和处理器拦截器)返回给DispatcherServlet

4、DispatcherServlet根据处理器Handler获取对应的适配器

5、HandlerAdapter调用具体的处理器Handler去处理请求

6、Handler(Controller)执行完成后返回ModelAndView

7、HandlerAdapter返回ModelAndView

8、DispatcherServlet统一将返回的ModelAndView派送到ViewResolve(视图解析器)解析

9,视图解析器解析之后返回View

10、对View进行渲染

11、响应用户

注意:如果controller方法上有@Responboby注解,说明要返回的是json对象,那么就

Handler处理完就会生成json对象,不会再去进行视图渲染那步了。

2.Spring MVC 获取表单数据的几种方式

Controller层的方法,添加 HttpServletRequst 类型入参,通过HttpServletRequst.getParameter() 获取请求数据。

Controller层的方法,添加对应表单字段 name 的参数,有几个表单字段就添加多少个对应的入参。

用户名:<input type="text" name="user">

密码:   <input type="password" name="pw">

Controller层的方法,添加自定义 Java 对象类型的入参,并添加@ModelAttribute 注解,由这个入参对象接收表单提交的数据。 当表单字段名与方法的形参对象名不一致时,可以在参数类型前添加@RequestParam(“表单字段名”)注解来获取表单参数。

3.SpringMVC怎么样设定重定向和转发的?

(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"

(2)重定向:在返回值前面加"redirect:",譬如"redirect:百度一下,你就知道"

4.如何解决POST请求中文乱码问题,GET的又如何处理呢?

(1)解决post请求乱码问题:

在web.xml中配置一个 CharacterEncodingFilter 过滤器,设置成utf-8;

<filter>  <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>

(2)get请求中文参数出现乱码解决方法由TomCat处理

①修改tomcat配置文件添加编码与工程编码一致,如下:

<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

②另外一种方法对参数进行重新编码:

String userName = new String (request.getParamter("userName").getBytes("ISO8859-1"), "utf-8");

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。

5.SpringMvc是不是单例模式,如果是,有什么问题,怎么解决?

在Spring中,加了@Controller注解的类默认是单例模式;所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,

解决方案是在控制器里面不能写成员变量。

比如说不可以使用:

public HttpServletRequest request;public HttpServletResponse response;

可以改为:

@Resourcepublic HttpServletRequest request;@Autowiredpublic HttpServletResponse response;

在bean中注入作为成员变量的HttpServletRequest时,实际注入的是spring框架生成的代理对象,是ObjectFactoryDelegatingInvocationHandler的实例。在我们调用这个成员变量的方法时,最终是调用了objectFactory的getObject()对象的对应方法,在这里objectFactory是RequestObjectFactory这个类的对象。

RequestObjectFactory的getObject方法是从RequestContextHolderthreadlocal中去取值的。

请求刚进入springmvc的dispatcherServlet的时候会把request相关对象设置到RequestContextHolder的threadlocal中去.

为什么设计成单例模式?

①提高性能(不用每次请求都创建对象)

②不需要多例(不要在控制器类中定义成员变量)

6.SpringMVC文件上传步骤:

1.页面上,通过input来准备file组件,该标签,必须给定name属性值(该name不能和实体类的属性名一致) 同时,要求form表单必须给定一个属性:enctype="multipart/form-data"

<form action="uc/adduser" method="post" enctype="multipart/form-data">    <input type="file" name="pic" id="pic" /></form>

2.在pom.xml文件中,添加文件上传的第三方工具:

<!-- 文件上传依赖(该依赖下载时,commons-io-2.2.jar也随着添加到依赖中) --><dependency>    <groupId>commons-fileupload</groupId>    <artifactId>commons-fileupload</artifactId>    <version>1.3.2</version></dependency>

3.在app-springmvc.xml配置文件中,准备上传操作的对象:CommonsMultipartResolver,在这个对象中,我们可以对文件大小,编码方式等进行设定

<!-- 图片上传 -->

<bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--每个文件上传大小-->    <property name="maxUploadSizePerFile" value="102400000"></property></bean>

4.在控制器中,通过@RequestParam MultipartFile pic这种方式,来接收页面传递的文件,这里,参数的名字必须与页面上file组件的name属性值一致。此时,在控制器中,已经能够正常地接收页面上传的文件了,下一步,就可以读取这个文件了。

7.SpringMVC常用的注解有哪些?

@RestController == @ResponseBody + @Controller

@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。

@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。

@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。

@PathVariable:路径中取值,用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri中的变量作为参数。

@RequestParam:接收请求体中的参数,封装成实体类或Map

8. @Autowired 与 @Resource 的区别:

@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。

1、共同点

两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。

2、不同点

(1)@Autowired

@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。

(2)@Resource

@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

注:最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性。

9.Spring MVC中的异常处理

方式一: 使用注解 @ExceptionHandler( 用在方法上) 或@ControllerAdvice(用在类上)实现处理异常(AOP思想)

(1) @ExceptionHandler: 加在方法上,并且在运行时有效( 只能捕获本Controller 中发生的异常)

@ControllerPublicclass XX {/*@ExceptionHandler(ArithmeticException.class):只能精确匹配异常类型,匹配到了,则执行该方法,若不匹配,则继续报错@ExceptionHandler(Exception.class):拦截所有异常,只要有一场就执行该异常的方法*/@ExceptionHandler(ArrayIndexOutOfBoundsException.class)Public String method(ArithmeticExceptione) {    System.out.println("错误信息:"+e.getMessage());    Return "error";    }}

(2) 使用 @ControllerAdvice : 它是一个控制器增强功能注解,加在类上,会将该类中所有使用了@ExceptionHandler 注解的方法都应用到请求处理方法上测试代码:先精确匹配异常类型,若匹配不到,则最后再匹配 Exception 类。

// 告知spring容器这是个全局捕获异常类
@ControllerAdvice
public class GlobalExceptionAdvice {

@ExceptionHandler(Exception.class)
public String exception1(Exception e) {    
    System.out.println(e.getMessage());    
    return "error";
    }

@ExceptionHandler(ArithmeticException.class)
public String exception2(ArithmeticException e) {    
    System.out.println(e.getMessage());    
    return "error";
    }    
}

方式二: 使用 SimpleMapperingExceptionResolver 进行异常处理

(1) 在 spring.xml 文件中配置:

<beanclass="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><!--定义默认的异常处理页面,当该异常类型注册时使用-->     <propertyname="defaultErrorView"value="error"/><!--定义异常处理页面用来获取异常信息的变量名,默认名为exception-->     <propertyname="exceptionAttribute"value="ex"/><!--定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值-->      <propertyname="exceptionMappings">              <props>                      <propkey="java.lang.ArrayIndexOutOfBoundsException">error1</prop>               <propkey="java.lang.ArithmeticException">error2</prop>                    </props>       </property></bean>

(2) 模拟异常的处理方法:

@RequestMapping("/testSimpleMapingExceptionResolver")Public String testSimpleMapingExceptionResolver(@RequestParam("i") int i){    String[] values = new String[10];    System.out.println(values[i]);    Return "success";}

(3) 写一个展示error的前端页面:

10.Spring Boot 中如何解决跨域问题 ?

浏览器的同源策略会导致导致不能向其他域发送异步请求。

1.@CrossOrigin注解   

在每个Controller类上@CrossOrigin 注解,就可以解决跨域问题;

我们可以看到 @CrossOrigin 注解里面有几个常用的属性:

1、String[] origins:设置允许来源域名的列表;

2、String[] allowedHeaders:设置跨域请求中允许的请求头的字段类型;

3、String[] exposedHeaders:设置请求头的一些字段信息;

4、RequestMethod[] mehotds:跨域请求中支持的HTTP请求类型;

5、String allowCredentials:设置跨域请求中Response头中的’Access-Control-Allow-Credentials’字段值;

6、long maxAge:设置预检请求响应的缓存持续最大时间;

2.  GateWay网关解决

在application.yml里配置: 

cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有请求
            allowedOrigins: "*" #跨域处理 允许所有的域
            allowedMethods: # 支持的方法
            - GET
            - POST
            - PUT
            - DELETE

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值