目录
4.如何解决POST请求中文乱码问题,GET的又如何处理呢?
5.SpringMvc是不是单例模式,如果是,有什么问题,怎么解决?
8. @Autowired 与 @Resource 的区别:
1.MVC执行流程
![8030ab6dc1554e6589dffe82403a9dbe.png](https://i-blog.csdnimg.cn/blog_migrate/cd1692c85adaba246206677da966fb18.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方法是从RequestContextHolder的threadlocal中去取值的。
请求刚进入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