SpringMVC

原创
2016/12/19 20:21
阅读数 209

SpringMVC

    当需要学习一个新的MVC框架需要从以下方面入手:

1、环境搭建:(实现helloworld)

2、如何完成Controller和Viewer的映射

3、如何传递参数到控制器Controller

4、如何从控制器Controller获取参数传递给Viewer

5、页面标签使用

6、如何完成文件的上传

7、如何完成验证

8、异常的处理

9、深入学习一些原理和源代码的学习

一、SpringMVC整体架构

二、环境搭建

2.1、配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
	<servlet>
		<!-- hello的名称必须与WEB-INF下hello-servlet.xml的名称对应 -->
		<servlet-name>hello</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 项目启动时启动 -->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>hello</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

2.2、配置xxx-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
	
	<!-- 一般开发中会使用:基于annotation的方式 -->
	<!-- 打开annotation并设置去哪些包中去查找annotation -->
	<context:component-scan base-package="org.pm.controller"/>
	<mvc:annotation-driven/>
	
	<!-- 下面的方法基本不会使用 -->
	<bean name="/welcome.html" class="org.pm.controller.WelcomeController"/>

	<!-- Viewer,一般使用InternalResourceViewResolver -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 前缀 -->
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<!-- 后缀 -->
		<property name="suffix" value=".jsp"/>
	</bean>

</beans>

2.3、控制器Controller

@Controller
public class HelloController {
	//RequestMapping表示用哪个url来对应,是个String[]数组可以传多个值
	@RequestMapping({"/hello","/"})
	//1、可以通过@RequestParam进行参数传值,特别注意:使用@RequestParam进行传值时必须指定参数,否则会报错
	//2、可以直接进行参数传值,如果不指定参数值则为null
	//3、通过Map传值到Viewer,但是不建议使用
	//4、建议使用Model传值到Viewer
	public String hello(String username,Model model) {
		System.out.println("hello");
		model.addAttribute("username", username);
		//此时用哪个作为key?它默认是使用对象的类型作为key-->model.addAttribute("string",username);
		//可以在传递对象的时候使用:model.addAttribute(new User());-->model.addAttribute("user",new User());
		model.addAttribute(username);
		System.out.println(username);
		return "hello";
	}
	
	@RequestMapping("/wel")
	public String welcome() {
		return "welcome";
	}
}

    页面获取Controller传递的参数值:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Hello!!${username }</h1>
${string }
</body>
</html>

2.4、Viewer:HandlerMapping

    web.xml:

	<!-- Viewer,一般使用InternalResourceViewResolver -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 前缀 -->
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<!-- 后缀 -->
		<property name="suffix" value=".jsp"/>
	</bean>

例子:

Controller

Controller
@RequestMapping("/user")
public class UserController {
	private Map<String,User> users = new HashMap<String,User>();
	
	public UserController() {
		users.put("zs", new User("zs", "123", "张三", "zs@zs.com"));
		users.put("ls", new User("ls", "123", "李四", "ls@ls.com"));
		users.put("ww", new User("ww", "123", "王五", "ww@ww.com"));
		users.put("zl", new User("zl", "123", "赵六", "zl@zl.com"));
	}
	
	@RequestMapping(value="/users",method=RequestMethod.GET) //只有get请求才会执行
	public String list(Model model) {
		model.addAttribute("users",users);
		return "/user/list";
	}
	
	//链接到add页面时是GET请求,会访问这段代码
	@RequestMapping(value="/add",method=RequestMethod.GET)
	public String add(Model model) {
		//开启modelDriven的两种方法:
		//1、add(Model model),model.addAttribute(new User());
		//2、add(@ModelAttribute("user") User user)
		model.addAttribute(new User());
		return "/user/add";
	}
	
	//在具体添加用户时,是post请求,就访问以下代码
	@RequestMapping(value="/add",method=RequestMethod.POST)
	public String add(@Validated User user,BindingResult br,MultipartFile[] attachs,HttpServletRequest req) throws IOException {//一定要紧跟@Validated之后写验证结果类BindingResult,两个之间不能有其它的内容
		if(br.hasErrors()) {
			//如果有错误直接跳转到add视图
			return "/user/add";
		}
		String realpath = req.getSession().getServletContext().getRealPath("/resources/upload");
		System.out.println(realpath);
		for(MultipartFile attach:attachs) {
			if(attach.isEmpty()) continue;
			File f = new File(realpath+"/"+attach.getOriginalFilename());
			FileUtils.copyInputStreamToFile(attach.getInputStream(), f);
		}
		users.put(user.getUsername(), user);
		return "redirect:/user/users";
	}
	
	@RequestMapping(value="/{username}",method=RequestMethod.GET)
	public String show(@PathVariable String username,Model model) {
		model.addAttribute(users.get(username));
		return "/user/show";
	}
	
	//通过params获取json数据
	@RequestMapping(value="/{username}",method=RequestMethod.GET,params="json")
	@ResponseBody
	public User show(@PathVariable String username) {
		return users.get(username);
	}
	
	@RequestMapping(value="/{username}/update",method=RequestMethod.GET)
	public String update(@PathVariable String username,Model model) {
		model.addAttribute(users.get(username));
		return "user/update";
	}
	
	//警告: Skipping URI variable 'username' since the request contains a bind value with the same name.
	//造成这个Warning的原因是:url的path和表单中都有username 变量,这个时候,把url path改成别的名字就好了。
	@RequestMapping(value="/{us}/update",method=RequestMethod.POST)
	public String update(@PathVariable String us,@Validated User user,BindingResult br) {
		if(br.hasErrors()) {
			return "user/update";
		}
		users.put(us, user);
		return "redirect:/user/users";
	}
	
	@RequestMapping(value="/{username}/delete",method=RequestMethod.GET)
	public String delete(@PathVariable String username) {
		users.remove(username);
		return "redirect:/user/users";
	}
	
	@RequestMapping(value="/login",method=RequestMethod.POST)
	public String login(String username,String password,HttpSession session) {
		if(!users.containsKey(username)) {
			throw new UserException("用户名不存在");
		}
		User u = users.get(username);
		if(!u.getPassword().equals(password)) {
			throw new UserException("用户密码不正确");
		}
		session.setAttribute("loginUser", u);
		return "redirect:/user/users";
	}
	
	/**
	 * 局部异常处理,仅仅只能处理这个控制器中的异常
	 */
	/*@ExceptionHandler(value={UserException.class})
	public String handlerException(UserException e,HttpServletRequest req) {
		req.setAttribute("e", e);
		return "error";
	}*/
}

xxx-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
	
	<!-- 一般开发中会使用:基于annotation的方式 -->
	<!-- 打开annotation并设置去哪些包中去查找annotation -->
	<context:component-scan base-package="org.pm.controller"/>
	<mvc:annotation-driven>
		<!-- 配置json转换器 -->
		<!-- <mvc:message-converters>
			<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
			<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
		</mvc:message-converters> -->
	</mvc:annotation-driven>
	<!-- 将静态文件指定到某个特殊的文件夹中统一处理 -->
	<!-- /*代表当前文件夹下的所有文件,/**代表当前文件夹下的所有文件及子文件夹下的所有文件 -->
	<mvc:resources location="/resources/" mapping="/resources/**"/>
	
	<!-- 下面的方法基本不会使用 -->
	<bean name="/welcome.html" class="org.pm.controller.WelcomeController"/>
	
	<!-- Viewer,一般使用InternalResourceViewResolver -->
	<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- Spring对JSTL的支持,可以不加这个属性 -->
		<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> -->
		<!-- 前缀 -->
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<!-- 后缀 -->
		<property name="suffix" value=".jsp"/>
	</bean>
	
	<!-- 设置multipartResolver才能完成文件的上传 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="5000000"/>
	</bean>
	
	<!-- 全局异常处理 -->
	<bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<!-- 可以定义多个异常处理 -->
				<prop key="org.pm.model.UserException">error</prop>
				<!-- <prop key="java.lang.NullPointException">exception</prop> -->
			</props>
		</property>
	</bean>

</beans>

 

展开阅读全文
打赏
0
7 收藏
分享
加载中
写的不错,适合入门者学习
2017/11/05 18:46
回复
举报
更多评论
打赏
1 评论
7 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部