JavaEE:Spring MVC使用

说明:

MVC:替换Servlet,拦截请求与控制页面跳转,类似于Struts框架。

导入依赖jar包:spring-web-x.x.x.RELEASE、spring-webmvc-x.x.x.RELEASE、spring-core-x.x.x.RELEASE.jar、spring-context-x.x.x.RELEASE.jar、spring-beans-x.x.x.RELEASE.jar、spring-aop-x.x.x.RELEASE.jar

通用依赖jar包:commons-logging-x.x.jar、log4j-x.x.xx.jar

一、创建"请求处理类(类似Servlet),处理带参请求,带参页面跳转等:

1.使用@Controller配置当前类为页面求处理类:

(1)路径无子目录方式:

@Controller
public class LoginControl {
...
}

(2)路径有子目录方式:

@Controller
@RequestMapping("dir1")  //给路径加上子目录,访问路径为:http://.../根目录/dir1/login.acion
//@RequestMapping(value = "dir1")  //同上
public class LoginControl {
...
}

(3)限制请求方式(GET、POST等):

@Controller
@RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }) // 限制请求方式为GET或POST
//@RequestMapping(method = RequestMethod.POST ) // 同上
public class LoginControl {
...
}

2.使用@RequestMapping映射路径<->方法,在LoginControl类中增加方法:

(1)无传参方式:

@RequestMapping("login")    //拦截后缀为login.action的请求,如http://.../根目录/login.action
//@RequestMapping(value={"login","login2"}) //同上,支持多个路径
public String login() {
	...
}

(2)基本类型传参方式:
参数类型说明:整型、字符串、单精度、双精度、布尔型
get方式访问地址:http://.../根目录/login.action?mobile=13000

@RequestMapping("login")
public ModelAndView login(@RequestParam("mobile")String phone) { //@RequestParam()表示取出mobile参数的值,赋值给phone
//public ModelAndView login(@RequestParam(value = "mobile", required = true, defaultValue = "123") String phone) { //同上,required表示必传,defaultValue为默认值
	...
}

(3)对象类型传参方式,传的参数名称必须与对象属性名一样,属性必须有set方法:
get方式访问地址:http://.../根目录/login.action?phone=13000
传参方式:属性名,如phone=13000

@RequestMapping("login")
public String login(User user) {
	...
}

User.java(对象类型):

public class User {
	public String phone;

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}
	
}

(4)包装对象类型传参方式:
get方式访问地址:http://192.168.1.2:8080/根目录/login.action?user.phone=13000
传参方式:类属性名.基本属性名,如user.phone=13000

@RequestMapping("login")
public String login(UserWrap userWrap) {
	...
}

UserWrap.java(包装对象类型):

public class UserWrap {
	public User user;
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
}

(5)数组类型传参方式:
页面表单请求:

<form action="/根目录/login.action" method="post">
	<input type="text" name="keys">
	<input type="text" name="keys">
	<input type="submit">
</form>

接收请求:

@RequestMapping("login")
public String login(int[] keys) {
	...
}

(6)List类型传参方式(要和对象类型组合使用):
页面表单请求:

<form action="/TestWeb/login.action" method="post">
	<input type="text" name="keys"> <!-- 此keys对应User的keys属性 -->
	<input type="text" name="keys"> <!-- 此keys对应User的keys属性 -->
	<input type="submit">
</form>

接收请求:

@RequestMapping("login")
public String login(User user, Model model) {
	...
}

User.java:

public class User {
	public List<String> keys;  //此keys属性对应页面表单的name="keys"
	public List<String> getKeys() {
		return keys;
	}
	public void setKeys(List<String> keys) {
		this.keys = keys;
	}
}

3.控制页面跳转:

(1)return ModelAndView方式:

@RequestMapping("login")
public ModelAndView login() {
	ModelAndView mav = new ModelAndView();
	//传参给要跳转的页面
	mav.addObject("key", "value");
	//跳转到指定页(需要配置跳转路径前/后缀):/WEB-INF/jsp/LoginSuccess.jsp
	mav.setViewName("LoginSuccess");
	return mav;
}

(2)return 字符串方式:

@RequestMapping("login")
public String login(Model model) {
	//传参给要跳转的页面
	model.addAttribute("key", "value");
	//跳转到指定页(需要配置跳转路径前/后缀):/WEB-INF/jsp/LoginSuccess.jsp
 	return "LoginSuccess";
	//return "forward:home.html";//转发,不能访问WEB-INF下的页面
	//return "redirect:home.html";//重定向,不能访问WEB-INF下的页面
}

(3)Servlet方式:

@RequestMapping("login")
public void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	// 获取传参
	String value = req.getParameter("key");
	System.out.println(value);
	// 传参给要跳转的页面
	req.setAttribute("key2", "value2");
	// 跳转到指定页(转发)
	req.getRequestDispatcher("/WEB-INF/jsp/LoginSuccess.jsp").forward(req, resp);
}

二、配置"请求处理类",在spring-mvc.xml中配置包扫描(src目录下):

1.配置映射器+适配器:

方法一:

<?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 
	https://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	">
	<!-- 配置包扫描,实例化LoginControl.java -->
	<context:component-scan base-package="com.yyh.hkw.control"/>
	<!-- 配置映射器,处理请求路径到方法的调用 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
	<!-- 配置适配器,处理请求路径到方法的调用 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
</beans>

方法二:

<beans>
	<!-- 配置包扫描,实例化LoginControl.java -->
	<context:component-scan base-package="com.yyh.hkw.control"/>
	<!-- 配置注解驱动,等同于配置映射器+适配器,处理请求路径到方法的调用-->
	<mvc:annotation-driven />
</beans>

2.在<beans>节点中,配置跳转路径前/后缀(代码处路径少写前后缀):

<!-- 配置路径前/后缀,在跳转时可省略前/后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/jsp/" />
	<property name="suffix" value=".jsp" />
</bean>

三、配置请求拦截与编码过滤器(类似servlet配置),在web.xml中:

1.配置拦截*.action后缀的请求路径,在<web-app>节点中加入:

<?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_4_0.xsd"
	metadata-complete="true" version="4.0">
	<welcome-file-list>
		<welcome-file>home.html</welcome-file>
	</welcome-file-list>
	<!-- 配置拦截*.action后缀的请求路径 -->
	<servlet>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 加载spring-mvc.xml文件 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
</web-app>

2.配置编码过滤器(处理乱码),在<web-app>节点中加入:

<!-- 编码过滤器(处理乱码) -->
<filter>
	<filter-name>encoding</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>encoding</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

四、日期转换器(将表单字符串转换为Date类型传参给请求控制类):

1.创建自定义日期转换类,实现org.springframework.core.convert.converter.Converter:

//日期转换器
public class DateConvert implements Converter<String, Date> {
	@Override
	public Date convert(String srcDate) {
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
			return format.parse(srcDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
}

2.配置自定义日期转换类,在spring-mvc.xml文件<beans>节点内:

<!-- 自定义日期转换类,refDateConvert为自定义id值 -->
<bean id="refDateConvert" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
	<property name="converters">
		<set>
			<!-- 自定义的日期转换类 -->
			<bean class="com.yyh.hkw.domain.DateConvert"/>
		</set>
	</property>
</bean>
<!-- 配置注解驱动,等同于配置映射器+适配器,处理请求路径到方法的调用,refDateConvert为自定义日期转换类-->
<mvc:annotation-driven conversion-service="refDateConvert"/>

3.传递日期类型的参数,实现自动转换:
(1)User.java:

public class User {
	public Date date;//对应页面表单name="date"
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
}

(2)LoginControl.java:

@RequestMapping("login")
public String login(User user, Model model) {
	...
}

(3)页面表单请求:

<form action="/TestWeb/login.action" method="post">
	<input type="text" name="date"> <!-- name="date"对应User.date属性 -->
	<input type="submit">
</form>

五、全局异常处理:

1.自定义HandlerExceptionResolver实现类,处理全局异常:

//全局异常处理
public class GlobalException implements HandlerExceptionResolver {
	@Override
	public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object arg2, Exception e) {
		ModelAndView mav = new ModelAndView();
		//跳到错误页(需要配置跳转路径前/后缀):/WEB-INF/jsp/error.jsp
		mav.setViewName("error");
		return mav;
	}
}

2.配置全局异常处理类,在spring-mvc.xml的<beans>标签中:

<beans ...>
	...
	<!-- 配置全局异常处理类 -->
	<bean class="com.yyh.hkw.control.GlobalException"/>
</beans>

六、配置图片访问路径(Web Modules):

1.代码方式:
打开eclipse中Servers/Tomcat v9.0 Server at localhost-config/server.xml文件,在Host节点中插入如下代码:

<Context docBase="D:\JavaEEDevelop\apache-tomcat-9\images" path="/images" reloadable="true"/>

2.菜单操作方式:
(1)在eclipse中找到Servers控制台,选中"Tomcat v9.0 Server at localhost"。在新打开的面板中,选中Modules。在右侧点击"Add External Web Module...",如图所示:

(2)在"Add Web Module"弹出框中,Document base选中本地硬盘某个目录"D:\JavaEEDevelop\apache-tomcat-9\images",在Path中输入访问路径"/images",如图所示:

3.访问路径:
http://.../images/icon1.png

七、图片上传处理:

依赖jar包:commons-fileupload-x.x.jar、commons-io-x.x.jar

1.配置图片上传处理器:

<!-- 配置图片上传处理类,id值必须为multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<property name="maxUploadSize" value="1048576" /> <!-- 最大字节数,单位为B,此处为1*1024*1024 -->
</bean>

2.配置文件上传处理类:

//@Controller配置当前类为页面求处理类
@Controller
public class UploadControl {
	@RequestMapping("upload")
	public String upload(HttpServletRequest req, MultipartFile imgFile) { // MultipartFile表示文件类型,imgName和页面表单<input type="file" name="imgFile" />对应
		//获取上传的文件原名称
		String fileName = imgFile.getOriginalFilename();
		//得到文件存储目录
		String dir = req.getSession().getServletContext().getRealPath("/WEB-INF/file");
		File file = new File(dir, fileName);
		try {
			//将上传的文件写入指定路径
			imgFile.transferTo(file);
		} catch (IllegalStateException | IOException e) {
			e.printStackTrace();
		}
		return "UploadSuccess";  //跳到上传成功页
	}
}

3.Html表单代码:

<!-- multipart/form-data表示文件流 -->
<form action="/TestWeb/upload.action" enctype="multipart/form-data" method="post">
	<input type="file" name="imgFile" /><!--imgFile和获取的参数名保持一致 -->
	<input type="submit">
</form>

八、json格式的请求与返回处理:

依赖jar包:
jackson-annotations-x.x.x、jackson-core-x.x.x、jackson-databind-x.x.x

1.用@RequestBody将请求json字符串转换为对象:
请求json:

{"phone":"130000"}

实现代码:

@Controller
public class LoginControl {
	@RequestMapping("login")
	public String login(@RequestBody User user) { // @RequestBody将请求json字符串转换为对象
		...
	}
}

2.用@ResponseBody将返回对象转换为json字符串:
实现代码:

@Controller
public class LoginControl {
	@RequestMapping("login")
	@ResponseBody // @ResponseBody将返回对象转换为json字符串
	public User login() {
		User user = new User();
		user.setName("无名");
		return user;
	}
}

返回json:

{"name":"无名"}

九、Restful风格实现:

说明:url以id值结尾,区分不同的请求,如http://.../login/1

1.用{id}+@PathVariable实现路径后跟id值访问:

@Controller
public class LoginControl {
	@RequestMapping("login/{id}") //{id}不可更改,可在login后跟数值
	public String login(@PathVariable String id) { // @PathVariable用于将{id}的值取出,赋值给id
//	public String login(@PathVariable("id") String id2) { // 功能同上
		...
	}
}

2.配置拦截"/"后缀的请求路径(类似servlet配置),在<web-app>节点中加入:

<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
	...
	<servlet-mapping>
		...
		<!-- 配置拦截"/"后缀的请求路径 -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

十、拦截器 (类似Servlet的Filter):

1.自定义拦截类,实现HandlerInterceptor接口,用于拦截所有没登录的路径请求,跳登录页面:

(1)使用场景:
没登录时访问:http://.../根目录/pay.action,被拦截后跳到login.jsp
发起登录请求:http://.../根目录/LoginGroup/login.action,不会被拦截。

(2)实现:

public class RequestInterceptor implements HandlerInterceptor {
	// 1.preHandle方法在路径方法之前执行,return true为放行,return false为拦截
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if (request.getSession().getAttribute("token") == null) {//判断是否已经登录过,没登录跳登录输入页
			response.sendRedirect("/TestWeb/login.jsp");
		}
		return true;
	}
	// 2.postHandle方法在路径方法return之前执行,拦截时不执行此方法。
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
	}
	// 3.此方法在路径方法之后执行
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
	}
}

2.  配置拦截器,在 spring-mvc.xml的<beans>节点中加入,不拦截正常登录路径请求:

<!-- 配置拦截器 -->
<mvc:interceptors>
	<mvc:interceptor>
		<!-- 配置拦截的路径,"/**"为拦截所有请求,包含所有子目录 -->
		<mvc:mapping path="/**" />
		<!--配置不拦截的路径,此处配置不拦截登录路径组的所有请求 -->
		<mvc:exclude-mapping path="/LoginGroup/**" />
		<!--配置自定义拦截类 -->
		<bean class="com.yyh.hkw.control.RequestInterceptor" />
	</mvc:interceptor>
</mvc:interceptors>

3.登录请求处理类(处理正常登录请求,可以没有这一步):

@Controller
@RequestMapping("LoginGroup") //当前为登录路径组请求,已经配置为不会被拦截器拦截
public class LoginControl {
	@RequestMapping("login")
	public String login(String phone, String code, HttpSession session) {
		System.out.println("login");
		if("130".equals(phone) && "1".equals(code)) { //判断手机与验证码是否正确,正确通过,不正确跳登录界面
			session.setAttribute("token", "dsaf654sd6455464d4f5");  //设置token到session中
			return "/WEB-INF/jsp/login_success.jsp";  //跳登录成功界面
		}
		return "/login.jsp"; //跳登录输入界面
	}
}

十一、其他:

1.配置静态资源不拦截,在spring-config.xml的<beans>节点中加入:

<beans>
    ...
	<!-- 配置静态资源不拦截 -->
	<mvc:default-servlet-handler />
</beans>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值