admin管理员组

文章数量:1794759

SpringMVC面试题(2020版)

SpringMVC面试题(2020版)

SpringMVC和Struct2的区别

共同点:

  • 都是表现层框架,都是基于MVC模型编写的
  • 底层都离不开ServletAPI
  • 处理请求的机制是一个核心控制器 区别:
  • SpringMVC入口是Servlet,Struct2入口是Filter
  • SpringMVC是基于方法设计的,它是单例的。Struct2是基于类设计的,是多例的,每次都会重新创建处理对象,所以每次去执行操作时,SpringMV C会比Struct2快一些。
  • SpringMVC处理Ajax请求更方便。
  • Struct2的OGNL表达式开发效率比SpringMVC更高,但是执行效率并没有比JSTL表达式高。
springmvc入门程序

执行流程: 完整案例: index.jsp:

<h3>入门程序</h3> <a href="hello">入门程序</a>

HelloController.java:

// 控制器类 @Controller public class HelloController { @RequestMapping(path="/hello") public String sayHello(){ System.out.println("Hello StringMVC"); return "success"; } }

web.xml:

<web-app> <display-name>Archetype Created Web Application</display-name> <!--配置前端控制器--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--加载springmvc.xml配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!--一启动tomcat就创建DispatcherServlet对象,然后创建springmvc.xml文件--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>

resources中的springmvc.xml.

<!-- 开启注解扫描 --> <context:component-scan base-package="cn.itcast"/> <!-- 视图解析器对象 --> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 开启SpringMVC框架注解的支持 --> <mvc:annotation-driven/>

success.jsp:

<h3>入门成功</h3>

运行结果:

SpringMVC的消处理流程有了解吗?(重点)

各个组件的功能:

  • DispatcherServlet:前端控制器 控制整个流程的执行,调用其它组件处理用户请求
  • HandlerMapping:处理器映射器 根据用户请求找到Controller类中的映射方法,如:ControllerHello类中sayHello()
  • HandlerAdapter:处理器适配器 处理controller类中映射方法,并返回modelandview给前端控制器
  • ViewResolver:视图解析器 对modelandview进行解析,返回view
  • View:视图 浏览器将view渲染出来,返回给客户端
@RequestMapping注解(重点)

作用:建立请求URL和处理请求方法之间的对应关系 属性: path==value指定映射路径的 method指定请求方式。如:GET、POST、PUT、DELETE等 eg:

@RequestMapping(value="/testRequestMapping",method = {RequestMethod.GET}) public String testRequestMapping(){ System.out.println("测试RequestMapping注解..."); return "success"; }

params指定请求参数的条件,要求请求参数的key-value和配置的一模一样 eg:

@RequestMapping(value="/testRequestMapping",params = {"username=heihei"}) public String testRequestMapping(){ System.out.println("测试RequestMapping注解..."); return "success"; } <a href="user/testRequestMapping?username=heihei">RequestMapping注解</a>

headers:指定请求消头 eg:

@RequestMapping(value="/testRequestMapping",headers = {"Accept"}) public String testRequestMapping(){ System.out.println("测试RequestMapping注解..."); return "success"; }

浏览器中按F12进行调试就可以看到消头

绑定请求参数

入门级 执行流程: param.jsp:

<a href="param/testParam?username=hehe&password=123">请求参数绑定</a>

ParamController.java:

/** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 请求参数绑定入门 * @return */ @RequestMapping("/testParam") public String testParam(String username,String password){ System.out.println("执行了..."); System.out.println("用户名:"+username); System.out.println("密码:"+password); return "success"; }

运行结果: 把参数封装到javabean中的数据绑定(带有对象引用) 执行流程: Account.java:

public class Account implements Serializable{ private String username; private String password; private Double money; private User user; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "username='" + username + '\\'' + ", password='" + password + '\\'' + ", money=" + money + ", user=" + user + '}'; } }

User.java:

public class User implements Serializable{ private String uname; private Integer age; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "uname='" + uname + '\\'' + ", age=" + age + ", date=" + date + '}'; } }

param.jsp:

<form action="param/saveAccount" method="post"> 姓名:<input type="text" name="username" /><br/> 密码:<input type="text" name="password" /><br/> 金额:<input type="text" name="money" /><br/> 用户姓名:<input type="text" name="user.uname" /><br/> 用户年龄:<input type="text" name="user.age" /><br/> <input type="submit" value="提交" /> </form>

ParamController.java:

/** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 请求参数绑定把数据封装到JavaBean的类中 * @return */ @RequestMapping("/saveAccount") public String saveAccount(Account account){ System.out.println("执行了..."); System.out.println(account); return "success"; } }

运行结果: 带有集合类型的数据绑定 Account.java:

public class Account implements Serializable{ private String username; private String password; private Double money; private List<User> list; private Map<String,User> map; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public List<User> getList() { return list; } public void setList(List<User> list) { this.list = list; } public Map<String, User> getMap() { return map; } public void setMap(Map<String, User> map) { this.map = map; } @Override public String toString() { return "Account{" + "username='" + username + '\\'' + ", password='" + password + '\\'' + ", money=" + money + ", list=" + list + ", map=" + map + '}'; } }

User.java:

public class User implements Serializable{ private String uname; private Integer age; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "uname='" + uname + '\\'' + ", age=" + age + ", date=" + date + '}'; } }

param.jsp:

<form action="param/saveAccount" method="post"> 姓名:<input type="text" name="username" /><br/> 密码:<input type="text" name="password" /><br/> 金额:<input type="text" name="money" /><br/> 用户姓名:<input type="text" name="list[0].uname" /><br/> 用户年龄:<input type="text" name="list[0].age" /><br/> 用户姓名:<input type="text" name="map['one'].uname" /><br/> 用户年龄:<input type="text" name="map['one'].age" /><br/> <input type="submit" value="提交" /> </form>

ParamController.java:

@RequestMapping("/saveAccount") public String saveAccount(Account account){ System.out.println("执行了..."); System.out.println(account); return "success"; }

运行结果:

配置解决中文乱码的过滤器

发送请求后,控制台出现乱码: 解决: web.xml:

<!--配置解决中文乱码的过滤器--> <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>

解决后:

自定义类型转换器

我们在页面中输入数据时,它都是按照字符串类型进行处理的,但是我么后台中各种数据类型划分明确,它是如何将字符串类型转换成后台中对应的数据类型呢!这就是SpringMVC框架为我们做好的-----类型转换器。 但是有些类型可能框架无法转换,如:日期类型-写法2014-09-03无法转换,但是/写法可以转换2014/09/03。 这需要我们自定义类型转换器

步骤:

  • 编写具有类型转换功能类
  • 配置类型转换器,让前端控制器能够找到它
  • 在类型转换器中注入转换功能功能类
  • 让类型转换器生效
  • User.java:

    public class User implements Serializable{ private String uname; private Integer age; private Date date; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } @Override public String toString() { return "User{" + "uname='" + uname + '\\'' + ", age=" + age + ", date=" + date + '}'; } }

    param.jsp:

    <form action="param/saveUser" method="post"> 用户姓名:<input type="text" name="uname" /><br/> 用户年龄:<input type="text" name="age" /><br/> 用户生日:<input type="text" name="date" /><br/> <input type="submit" value="提交" /> </form>

    ParamController.java:

    @Controller @RequestMapping("/param") public class ParamController { /** * 自定义类型转换器 * @param user * @return */ @RequestMapping("/saveUser") public String saveUser(User user){ System.out.println("执行了..."); System.out.println(user); return "success"; } }

    类型转换代码:

    /** * 把字符串转换日期 */ public class StringToDateConverter implements Converter<String,Date>{ /** * String source 传入进来字符串 * @param source * @return */ public Date convert(String source) { // 判断 if(source == null){ throw new RuntimeException("请您传入数据"); } DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { // 把字符串转换日期 return df.parse(source); } catch (Exception e) { throw new RuntimeException("数据类型转换出现错误"); } } }

    springmvc.xml:

    <!--配置自定义类型转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.itcast.utils.StringToDateConverter"/> </set> </property> </bean> <!-- 让类型转换器生效 --> <mvc:annotation-driven conversion-service="conversionService"/> SpringMVC常用注解(重点)
    • @RequestParam 作用:把请求中指定名称的参数给控制器中形参赋值 使用地方:方法形参上 属性: value==name指定参数的名称 required指定请求参数中是否必须提供参数,默认值为true。

    anno.jsp:

    <a href="anno/testRequestParam?dname=哈哈">RequestParam</a>

    AnnoController.java:

    运行结果:

    @requestparam案例再重现 @requestparam案例再现

    • @RequestBody 作用:获取请求体的内容,得到的是key=value&key=value…结构的数据 使用地方:方法形参上 属性: required指定是否必须有请求体,默认值为true 细节:对GET请求方式没用
    <form action="anno/testRequestBody" method="post"> 用户姓名:<input type="text" name="username" /><br/> 用户年龄:<input type="text" name="age" /><br/> <input type="submit" value="提交" /> </form> /** * 获取到请求体的内容 * @return */ @RequestMapping("/testRequestBody") public String testRequestBody(@RequestBody String body){ System.out.println("执行了..."); System.out.println(body); return "success"; }

    运行结果:

    restful风格 优点:结构清晰、易于理解、方便扩展

    • @PathVariable 作用:指定请求的URL路径里面的变量 使用地方:方法的形参上 属性: name==value指定参数的名称
    <a href="anno/testPathVariable/10">testPathVariable</a> @Controller @RequestMapping("/anno") public class AnnoController { /** * PathVariable注解 * @return */ @RequestMapping(value="/testPathVariable/{sid}") public String testPathVariable(@PathVariable(name="sid") String id){ System.out.println("执行了..."); System.out.println(id); return "success"; } }

    运行结果:

    • @RequestHeader 作用:获取请求头的值 使用地方:方法的形参上 属性: value指定请求头类型,如:Accept等
    <a href="anno/testRequestHeader2">RequestHeader</a> @Controller @RequestMapping("/anno") public class AnnoController { /** * 获取请求头的值 * @param header * @return */ @RequestMapping(value="/testRequestHeader2") public String testRequestHeader2(@RequestHeader(value="Accept") String header){ System.out.println("执行了..."); System.out.println(header); return "success"; } }

    运行结果:

    • @RequestAttribute 作用:获取request请求域中的值 作用地方:方法的形参上 属性:required 指定是否必须有请求域,默认值是true

    • @CookieValue 作用:用于把指定的cookie名称值给控制器方法形参赋值 使用地方:方法的形参上 属性: value指定参数名,如:JSESSIONID

    anno.jsp:

    <a href="anno/testCookieValue">CookieValue</a>

    AnnoController.java:

    @Controller @RequestMapping("/anno") public class AnnoController { /** * 获取Cookie的值 * @return */ @RequestMapping(value="/testCookieValue") public String testCookieValue(@CookieValue(value="JSESSIONID") String cookieValue){ System.out.println("执行了..."); System.out.println(cookieValue); return "success"; } }

    运行结果:

    • @ModelAttribute 作用:出现在方法上,表示当前方法会在控制器方法执行之前先执行 出现在参数上,获取指定的数据给参数赋值 出现位置:方法上和参数上都可以

    执行流程: @ModelAttribute注解修饰的方法有返回值 anno.jsp:

    <form action="anno/testModelAttribute" method="post"> 用户姓名:<input type="text" name="uname" /><br/> 用户年龄:<input type="text" name="age" /><br/> <input type="submit" value="提交" /> </form> @Controller @RequestMapping("/anno") public class AnnoController { /** * ModelAttribute注解 * @return */ @RequestMapping(value="/testModelAttribute") public String testModelAttribute( User user){ System.out.println("testModelAttribute执行了..."); System.out.println(user); return "success"; } // 该方法会先执行 @ModelAttribute public User showUser(String uname){ System.out.println("showUser执行了..."); // 通过用户查询数据库(模拟) User user = new User(); user.setUname(uname); user.setAge(20); user.setDate(new Date()); return user; } }

    运行结果: @ModelAttribute注解修饰的方法没有返回值(用在参数上)

    执行流程: anno.jsp:

    <form action="anno/testModelAttribute" method="post"> 用户姓名:<input type="text" name="uname" /><br/> 用户年龄:<input type="text" name="age" /><br/> <input type="submit" value="提交" /> </form>

    AnnoController.java:

    @Controller @RequestMapping("/anno") public class AnnoController { /** * ModelAttribute注解 * @return */ @RequestMapping(value="/testModelAttribute") public String testModelAttribute(@ModelAttribute("abc") User user){ System.out.println("testModelAttribute执行了..."); System.out.println(user); return "success"; } @ModelAttribute public void showUser(String uname, Map<String,User> map){ System.out.println("showUser执行了..."); // 通过用户查询数据库(模拟) User user = new User(); user.setUname(uname); user.setAge(20); user.setDate(new Date()); map.put("abc",user); } }
    • @SessionAttributes 作用:用于多次执行控制器方法间参数共享 使用地方:类上 属性:value==names指定request域中的key

    在页面中获取session域中数据: 执行流程: anno.jsp:

    <a href="anno/getSessionAttributes">getSessionAttributes</a> <a href="anno/delSessionAttributes">delSessionAttributes</a> <a href="anno/testSessionAttributes">testSessionAttributes</a>

    AnnoController.java:

    @Controller @RequestMapping("/anno") @SessionAttributes(value={"msg"}) // 把msg=美美存入到session域对中 public class AnnoController { /** * 把数据存储到request域中 * @return */ @RequestMapping(value="/testSessionAttributes") public String testSessionAttributes(Model model){ System.out.println("testSessionAttributes..."); // 把数据存储到request域中 model.addAttribute("msg","美美"); return "success"; } /** * 获取到session域中数据 * @param modelMap * @return */ @RequestMapping(value="/getSessionAttributes") public String getSessionAttributes(ModelMap modelMap){ System.out.println("getSessionAttributes..."); String msg = (String) modelMap.get("msg"); System.out.println(msg); return "success"; } /** * 清除session域中的数据 * @param status * @return */ @RequestMapping(value="/delSessionAttributes") public String delSessionAttributes(SessionStatus status){ System.out.println("getSessionAttributes..."); status.setComplete(); return "success"; } }

    在页面中取出session域中的数据 success.jsp:

    <h3>入门成功</h3> ${sessionScope}

    运行结果:

    响应之返回值是字符串类型

    执行流程: 浏览器发送请求>>>后台查出数据,存到model对象中,然后存到request域中>>>跳转页面,将request域中数据取出来 response.jsp:

    <a href="user/testString" >testString</a>

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testString") public String testString(Model model){ System.out.println("testString方法执行了..."); // 模拟从数据库中查询出User对象 User user = new User(); user.setUsername("美美"); user.setPassword("123"); user.setAge(30); // model对象 model.addAttribute("user",user); return "success"; } }

    success.jsp:

    <h3>执行成功</h3> ${user.username} ${user.password} ${user.age}

    运行结果:

    响应之返回值是ModelAndView类型

    同返回值是字符串类型

    <a href="user/testModelAndView" >testModelAndView</a> @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ // 创建ModelAndView对象 ModelAndView mv = new ModelAndView(); System.out.println("testModelAndView方法执行了..."); // 模拟从数据库中查询出User对象 User user = new User(); user.setUsername("小凤"); user.setPassword("456"); user.setAge(30); // 把user对象存到ModelAndView对象中,然后会存储到request域中 mv.addObject("user",user); // 跳转到哪个页面 mv.setViewName("success"); return mv; } } <h3>执行成功</h3> ${user.username} ${user.password} ${user.age}

    运行结果:

    响应之返回值是void类型

    项目目录结构:

    • 请求转发
    <a href="user/testVoid" >testVoid</a> @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testVoid") public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("testVoid方法执行了..."); // 编写请求转发的程序 request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response); return; } }

    运行结果:

    • 重定向
    <a href="user/testVoid" >testVoid</a> @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testVoid") public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("testVoid方法执行了..."); // 重定向 response.sendRedirect(request.getContextPath()+"/index.jsp"); System.out.println(request.getContextPath()); return; } }

    运行结果:

    • 直接进行相应

    执行流程: 设置编码格式>>>设置浏览器解析格式和字符集>>>直接进行响应

    <a href="user/testVoid" >testVoid</a> @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testVoid") public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("testVoid方法执行了..."); // 设置中文乱码 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); // 直接会进行响应 response.getWriter().print("你好"); return; } }

    运行结果:

    请求转发和重定向的区别(重点)
    • 请求转发:
    request.getRequestDispatcher(URL).forward(request,response);

    处理流程: 1.客户端发送请求,servlet做出业务逻辑处理 2.servlet调用forward方法,服务器把目标资源返回给客户端

    • 重定向
    response.sendRedirect(URL地址)

    处理流程: 1.客户端发送请求,servlet做出业务逻辑处理 2.servlet调用sendRedirect()方法,把要访问的目标资源作为响应头返回给客户端 3.客户端再次访问服务器的xxx.jsp页面,服务器再次对客户端做出响应 区别: 1.请求转发在服务器内部转发,整个过程处于同一个请求中 2.重定向则是完全的跳转,浏览器会得到跳转后的地址,重新发送请求,整个过程处于两个请求中 3.请求转发中数据的存取可以使用request域:request.setAttribute(),request.getAttribute(),重定向是取不到request域的,只能使用session 4.请求转发在服务器内部进行,不能跨域、重定向可以跨域

    Ajax请求之异步请求(补) 响应json数据之发送Ajax请求

    页面发送ajax请求,后端拿到数据,并打印出来

    response.jsp:

    <script> // 页面加载,绑定单击事件 $(function(){ $("#btn").click(function(){ // alert("hello btn"); // 发送ajax请求 $.ajax({ // 编写json格式,设置属性和值 url:"user/testAjax", contentType:"application/json;charset=UTF-8", data:'{"username":"hehe","password":"123","age":30}', dataType:"json", type:"post", }); }); }); </script>

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { /** * 模拟异步请求响应 */ @RequestMapping("/testAjax") public void testAjax(@RequestBody String body){ System.out.println("testAjax方法执行了..."); System.out.println(body);// 做响应,模拟查询数据库 } }

    运行结果:

    响应json数据之响应json格式数据

    页面发送ajax请求,传的是json字符串数据,后端拿到json字符串数据给封装到user对象中,@ResponseBody把user对象转成json字符串数据再返回给页面。

    response.jsp:

    // 页面加载,绑定单击事件 $(function(){ $("#btn").click(function(){ // alert("hello btn"); // 发送ajax请求 $.ajax({ // 编写json格式,设置属性和值 url:"user/testAjax", contentType:"application/json;charset=UTF-8", data:'{"username":"hehe","password":"123","age":30}', dataType:"json", type:"post", success:function(data){ // data服务器端响应的json的数据,进行解析 alert(data); alert(data.username); alert(data.password); alert(data.age); } }); }); });

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { /** * 模拟异步请求响应 * @ResponseBody把user对象转成json字符串数据返回给页面 */ @RequestMapping("/testAjax") public @ResponseBody User testAjax(@RequestBody User user){ System.out.println("testAjax方法执行了..."); // 客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中 System.out.println(user); // 做响应,模拟查询数据库 user.setUsername("haha"); user.setAge(40); // 做响应 return user; } }

    运行结果:

    文件上传 传统方式上传

    执行流图: index.jsp:

    <form action="user/fileupload1" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="upload" /><br/> <input type="submit" value="上传" /> </form>

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { /** * 文件上传 * @return */ @RequestMapping("/fileupload1") public String fileuoload1(HttpServletRequest request) throws Exception { System.out.println("文件上传..."); // 使用fileupload组件完成文件上传 // 上传的位置 String path = request.getSession().getServletContext().getRealPath("/uploads/"); // 判断,该路径是否存在 File file = new File(path); if(!file.exists()){ // 创建该文件夹 file.mkdirs(); } // 解析request对象,获取上传文件项 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); // 解析request List<FileItem> items = upload.parseRequest(request); // 遍历 for(FileItem item:items){ // 进行判断,当前item对象是否是上传文件项 if(item.isFormField()){ // 说明普通表单向 }else{ // 说明上传文件项 // 获取上传文件的名称 String filename = item.getName(); // 把文件的名称设置唯一值,uuid String uuid = UUID.randomUUID().toString().replace("-", ""); filename = uuid+"_"+filename; // 完成文件上传 item.write(new File(path,filename)); // 删除临时文件 item.delete(); } } return "success"; } }

    运行结果:

    Springmvc框架文件上传

    原理图: springmvc.xml:

    <!--配置文件解析器对象--> <bean id="multipartResolver" class="org.springframework.web.multipartmons.CommonsMultipartResolver"> <!--字节单位--> <property name="maxUploadSize" value="10485760" /> </bean>

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { /** * SpringMVC文件上传 * @return */ @RequestMapping("/fileupload2") public String fileuoload2(HttpServletRequest request, MultipartFile upload) throws Exception { System.out.println("springmvc文件上传..."); // 使用fileupload组件完成文件上传 // 上传的位置 String path = request.getSession().getServletContext().getRealPath("/uploads/"); // 判断,该路径是否存在 File file = new File(path); if(!file.exists()){ // 创建该文件夹 file.mkdirs(); } // 说明上传文件项 // 获取上传文件的名称 String filename = upload.getOriginalFilename(); // 把文件的名称设置唯一值,uuid String uuid = UUID.randomUUID().toString().replace("-", ""); filename = uuid+"_"+filename; // 完成文件上传 upload.transferTo(new File(path,filename)); return "success"; } } 跨服务器上传

    图片经过应用服务器,上传到图片服务器 index.jsp:

    <form action="user/fileupload3" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="upload" /><br/> <input type="submit" value="上传" /> </form>

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { /** * 跨服务器文件上传 * @return */ @RequestMapping("/fileupload3") public String fileuoload3(MultipartFile upload) throws Exception { System.out.println("跨服务器文件上传..."); // 定义上传文件服务器路径 String path = "localhost:9090/uploads/"; // 说明上传文件项 // 获取上传文件的名称 String filename = upload.getOriginalFilename(); // 把文件的名称设置唯一值,uuid String uuid = UUID.randomUUID().toString().replace("-", ""); filename = uuid+"_"+filename; // 创建客户端的对象 Client client = Client.create(); // 和图片服务器进行连接 WebResource webResource = client.resource(path + filename); // 上传文件 webResource.put(upload.getBytes()); return "success"; } } springmvc异常处理

    步骤: 1.编写自定义异常类(做提示信的) 2.编写异常处理器代码 3.配置异常处理器(前端控制器能够找到它)

    执行流图: 自定义异常类:

    public class SysException extends Exception{ // 存储提示信的 private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public SysException(String message) { this.message = message; } }

    异常处理器:

    public class SysExceptionResolver implements HandlerExceptionResolver{ public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 获取到异常对象 SysException e = null; if(ex instanceof SysException){ e = (SysException)ex; }else{ e = new SysException("系统正在维护...."); } // 创建ModelAndView对象 ModelAndView mv = new ModelAndView(); mv.addObject("errorMsg",e.getMessage()); mv.setViewName("error"); return mv; } }

    index.jsp:

    <h3>异常处理</h3> <a href="user/testException" >异常处理</a>

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testException") public String testException() throws SysException { System.out.println("testException执行了..."); try { // 模拟异常 int a = 10/0; } catch (Exception e) { // 打印异常信 e.printStackTrace(); // 抛出自定义异常信 throw new SysException("查询所有用户出现错误了..."); } return "success"; } }

    springmvc.xml:

    <!--配置异常处理器--> <bean id="sysExceptionResolver" class="cn.itcast.exception.SysExceptionResolver"/>

    error.jsp:

    ${errorMsg}

    运行结果:

    拦截器

    作用:用于对处理器(Controller类中的方法)进行预处理和后处理

    拦截器和过滤器的区别 1.过滤器是servelt规范的一部分,任何javaweb工程都能使用 2.拦截器是springmvc框架自己的,只有使用springmvc框架工程才能使用 3.过滤器在url-pattern中配置/*,可以对所有要访问的资源进行拦截 4.拦截器只会拦截要访问的控制器中的方法(Controller类中的方法),对于jsp、html、js、css、image等无法拦截

    步骤: 1.编写拦截器类,实现HandlerInterceptor接口 2.配置拦截器,并在其中注册拦截器对象

    执行流图:

    index.jsp:

    <h3>拦截器</h3> <a href="user/testInterceptor" >拦截器</a>

    拦截器:

    public class MyInterceptor1 implements HandlerInterceptor{ /* * 预处理,controller方法执行前 * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法 * return false不放行 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor1执行了...前1111"); return true; }

    springmvc.xml:

    <!--配置拦截器--> <mvc:interceptors> <!--配置拦截器--> <mvc:interceptor> <!--要拦截的具体的方法--> <mvc:mapping path="/user/*"/> <!--不要拦截的方法 <mvc:exclude-mapping path=""/> --> <!--配置拦截器对象--> <bean class="cn.itcast.controller.itcast.interceptor.MyInterceptor1" /> </mvc:interceptor> </mvc:interceptors>

    UserController.java:

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testInterceptor") public String testInterceptor(){ System.out.println("testInterceptor执行了..."); return "success"; } }

    success.jsp:

    <h3>执行成功</h3>

    运行结果: 拦截器接口(HandlerInterceptor)中的方法 preHandler()预处理方法,在Controller类方法执行之前执行,可以提前跳转到其他页面 postHandler()后处理方法,在控制类方法执行之后和页面跳转之前执行,同样也可以提前跳转到其他页面 afterCompletion()在整个过程执行完之后执行,不可以跳转页面

    index.jsp:

    <h3>拦截器</h3> <a href="user/testInterceptor" >拦截器</a>

    拦截器1:

    public class MyInterceptor1 implements HandlerInterceptor{ /** * 预处理,controller方法执行前 * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法 * return false不放行 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor1执行了...前1111"); request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response); return true; } /** * 后处理方法,controller方法执行后,success.jsp执行之前 */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor1执行了...后1111"); request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response); } /** * success.jsp页面执行后,该方法会执行 */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor1执行了...最后1111"); } }

    拦截器2:

    public class MyInterceptor2 implements HandlerInterceptor{ /** * 预处理,controller方法执行前 * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法 * return false不放行 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor1执行了...前2222"); request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response); return true; } /** * 后处理方法,controller方法执行后,success.jsp执行之前 */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor1执行了...后2222"); request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response); } /** * success.jsp页面执行后,该方法会执行 */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor1执行了...最后2222"); } }

    处理器:

    @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/testInterceptor") public String testInterceptor(){ System.out.println("testInterceptor执行了..."); return "success"; } }

    springmvc.xml:

    <!--配置拦截器--> <mvc:interceptors> <!--配置拦截器--> <mvc:interceptor> <!--要拦截的具体的方法--> <mvc:mapping path="/user/*"/> <!--不要拦截的方法 <mvc:exclude-mapping path=""/> --> <!--配置拦截器对象--> <bean class="cn.itcast.controller.itcast.interceptor.MyInterceptor1" /> </mvc:interceptor> <!--配置第二个拦截器--> <mvc:interceptor> <!--要拦截的具体的方法--> <mvc:mapping path="/**"/> <!--不要拦截的方法 <mvc:exclude-mapping path=""/> --> <!--配置拦截器对象--> <bean class="cn.itcast.controller.itcast.interceptor.MyInterceptor2" /> </mvc:interceptor> </mvc:interceptors>

    success.jsp:

    <h3>执行成功</h3>

    运行结果:

    本文标签: 面试题springmvc