5. Interview-SSM

1 springmvc工作原理 / 执行流程

springmvc工作流程

2 springmvc方法怎么返回一个json

  • spring2.x做法:每个json视图controller配置一个Jsoniew。
如: 

或者

同样要用jackson的jar包。
  • 使用JSON工具将对象序列化成json,常用工具Jackson,fastjson,gson。

    • 利用HttpServletResponse,然后获取response.getOutputStream()或response.getWriter()直接输出。
  • 使用Springmvc3.x的注解@ResponseBody

3 SpringMVC的controller是单例还是多例?

  • springmvc的controller默认是单例的。
    • springmvc是基于方法的,用形参接收值,处理完毕就销毁。
    • springmvc的controller中不适合定义属性,会造成线程不安全。
    • springmvc设计默认单例,主要是为了提升性能。
  • springmvc可以修改为多例模式。
    • controller类上加注解@Scope("prototype")

4 springmvc常用哪些注解?

Spring MVC常用注解

5 Spring MVC的主要组件?

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

    • 接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
  • 处理器映射器HandlerMapping(不需要程序员开发)

    • 根据请求的URL来查找Handler
  • 处理器适配器HandlerAdapter

    • 在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
  • 处理器Handler(需要程序员开发)

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

    • 进行视图的解析,根据视图逻辑名解析成真正的视图(view)
  • 视图View(需要程序员开发jsp)

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

6 SpringMvc怎么和AJAX相互调用的?

通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象。具体步骤如下 :

  • 加入Jackson.jar
  • 在配置文件中配置json的映射
  • 在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解。

7 Springmvc 中拦截器如何使用?

  • 定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。

    • preHandle :进入 Handler方法之前执行,用于身份认证、身份授权,比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
    • postHandle:进入Handler方法之后,返回modelAndView之前执行,应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
    • afterCompletion:执行Handler完成执行此方法,应用场景:统一异常处理,统一日志处理
  • 拦截器配置:

    • 针对HandlerMapping配置(不推荐):springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该 拦截器。(一般不推荐使用)
    • 类似全局的拦截器:springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中

8 Springmvc 中对于文件的上传有哪些需要注意?

  • 在页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart类型的数据进行解析。
  • 在springmvc.xml中配置multipart类型解析器。
  • 方法中使用:MultipartFile attach (单个文件上传) 或者 MultipartFile[] attachs (多个文件上传)

9 Springmvc 中如何解决 GET | POST请求中文乱码问题?

GET方式

  • 每次发生请求之前对URL进行编码:
例如:Location.href="/encodeURI"(“http://localhost/test/s?name=中文&sex=女”);
  • 更简便的方法,在服务器端配置URL编码格式:修改tomcat的配置文件server.xml:
只需增加 URIEncoding=“UTF-8” 这一句,然后重启tomcat即可。


POST方式

  • 可以每次在request解析数据时设置编码格式:
request.setCharacterEncoding(“utf-8”);
  • 也可以使用编码过滤器来解决,最常用的方法是使用Spring提供的编码过滤器,在Web.xml中增加如下配置(要注意的是它的位置一定要是第一个执行的过滤器)

    charsetFilter
    org.springframework.web.filter.CharacterEncodingFilter
    
        encoding
        UTF-8
    
    
        forceEncoding
        true
    

该过滤器要做的其实就是强制为所有请求和响应设置编码格式:

request.setCharacterEncoding(“utf-8”);
response.setCharacterEncoding(“utf-8”);

10 Springmvc 怎么样设定重定向和转发的?

  • 在返回值前面加"forward:“就可以让结果转发,譬如"forward:user.do?name=method4”
  • 在返回值前面加"redirect:“就可以让返回值重定向,譬如"redirect:http://www.baidu.com”

11 Springmvc 如何做异常处理 ?

可以将异常抛给Spring框架,由Spring框架来处理;自定义实现spring的全局异常解析器HandlerExceptionResolver,在异常处理器中添视图页面即可。

12 Springmvc 中 如果拦截get方式提交的方法,怎么配置?

可以在@RequestMapping注解里面加上method=RequestMethod.GET

13 Springmvc 怎么样把ModelMap里面的数据放入Session里面?

可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。

14 Springmvc 和struts2的区别有哪些?

  • springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。
  • springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
  • Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

15 Springmvc 用什么对象从后台向前台传递数据的?

通过ModelMap对象,可以在这个对象里面用put方法,把对象加到里面,前台就可以通过el表达式拿到。

16 springmvc 中当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理?

要加上@ResponseBody注解。

17 项目使用mybatis开发流程是什么样的,需要做哪些事情?

  • 用java写interface
  • 写mapper.xml

18 mybatis没有接口实现类背后的原理是什么?

利用了jdk的动态代理。

    protected T newInstance(MapperProxy mapperProxy) {
        return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
    }

19 Mybatis缓存

Mybatis缓存机制
  • 一级缓存
    • 本地缓存,SqlSession级别,一级缓存默认是开启的,最多缓存1024条SQL
    • 同一个SqlSession再次发出相同的SQL,就从缓存中取数据,如果两次中间出现commit操作,本SqlSession中的一级缓存区域就会清空。
  • 二级缓存
    • 全局缓存,mapper级别,二级缓存是通过CacheExecutor实现的,CacheExecutor是Executor的代理对象。
    • 二级缓存默认是关闭的,开启二级缓存需要作如下配置:
      • mybatis全局配置中开启二级缓存配置
      • 对应的Mapper.xml中配置cache节点
      • 对应的select查询节点中添加useCache=true

20 Mybatis 是如何进行分页的?分页插件的原理是什么?

  • Mybatis 使用 RowBounds 对象进行分页,也可以直接编写 sql 实现分页,也可以使用Mybatis 的分页插件。

  • 分页插件的原理:实现 Mybatis 提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql。

举例:select from student,拦截 sql 后重写为:select t. from (select from student)t limit 0,10

21 简述 Mybatis 的插件运行原理,以及如何编写一个插件?

  • Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 通过动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。

  • 实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。

22 Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?

  • Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。
  • Mybatis 提供了 9 种动态 sql 标签:
    trim|where|set|foreach|if|choose|when|otherwise|bind。
  • 其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

23 #{}和${}的区别是什么?

  • '#{}是预编译处理,${}是字符串替换。
  • Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;
  • Mybatis 在处理{}替换成变量的值。
  • 使用#{}可以有效的防止 SQL 注入,提高系统安全性。

24 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?

  • Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
  • Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。

25 Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?

  • Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。

  • 它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。

26 请你说一下使用 MyBatis 的 mapper 接口调用时有哪些要求?

  • Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同
  • Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同
  • Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同
  • Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。

27 说说在使用JDBC 编程时,它有哪些不足之处,MyBatis 是如何解决这些问题的?

  • 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。
    • 解决:在 SqlMapConfig.xml 中配置数据连接池,使用连接池管理数据库连接。
  • Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
    • 解决:将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
  • 向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数一一对应。
    • 解决: Mybatis 自动将 java 对象映射至 sql 语句。
  • 对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对象解析比较方便。
    • 解决:Mybatis 自动将 sql 执行结果映射至 java 对象。

28 MyBatis 的好处是什么?

  • MyBatis 把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的
    维护带来了很大便利。
  • MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象,
    大大简化了 Java 数据库编程的重复工作。
  • 因为 MyBatis 需要程序员自己去编写 sql 语句,程序员可以结合数据库自身的特点灵活
    控制 sql 语句,因此能够实现比 Hibernate 等全自动 orm 框架更高的查询效率,能够完成复
    杂查询。

29 简述 Mybatis 的 Xml 映射文件和 Mybatis 内部数据结构之间的映射关系?

  • Mybatis 将所有 Xml 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。
  • 在Xml 映射文件中,标签会被解析为 ParameterMap 对象,其每个子元素会
    被解析为 ParameterMapping 对象。
  • 标签会被解析为 ResultMap 对象,其每个子元素会被解析为 ResultMapping 对象。
  • 每一个