SpringMvc

HelloControll.java:

@Controller
public class HelloControll {
	@RequestMapping("hello")//使方法能够接收请求,用于绑定请求地址
	public ModelAndView hello(){
		System.out.println("hello springmvc...");
		ModelAndView mav = new ModelAndView();
		//设置模型数据,用于传递到jsp
		mav.addObject("msg", "hello springmvc......");
		//设置视图名字,用于响应用户
		mav.setViewName("/WEB-INF/jsp/hello.jsp");		
		return mav;
	}
}

web.xml:

<!--核心控制器的配置  -->
  <servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	
  	<!-- 加载springmvc核心配置文件 -->
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:springmvc.xml</param-value>
  	</init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>

springmvc.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:p="http://www.springframework.org/schema/p"
	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.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- 配置controller扫描包 -->
	<context:component-scan base-package="com.itheima.springmvc.controller" />
</beans>

ItemController.java:

@Controller
public class ItemController
{
	@RequestMapping("itemList")
	public ModelAndView itemList() {
		ModelAndView mav = new ModelAndView();
		//模拟查询商品列表
		List<Item> list = Arrays.asList(new Item(1, "冰箱", 1999, new Date(), "冰箱很冷"),
						new Item(2,"冰箱2",1999,new Date(),"冰箱很凉"),
						new Item(3,"冰箱2",1999,new Date(),"冰箱很凉1"),
						new Item(4,"冰箱2",1999,new Date(),"冰箱很凉2"));
		mav.addObject("itemList",list);
		//mav.setViewName("/WEB-INF/jsp/itemList.jsp");
		mav.setViewName("itemList" );
		return mav;
	}
}
<form action="${pageContext.request.contextPath }/queryItem.action" method="post">

${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%> 。

也就是取出部署的应用程序名或者是当前的项目名称

比如我的项目名称是demo1在浏览器中输入为http://localhost:8080/demo1/a.jsp ${pageContext.request.contextPath}或<%=request.getContextPath()%>取出来的就是/demo1,而"/"代表的含义就是http://localhost:8080

故有时候项目中这样写${pageContext.request.contextPath}/a.jsp

HandlerMapping:处理器映射器,用于绑定url请求是由哪个方法来处理

HanderAdapoter:处理器适配器,用于实例化控制器并调用控制器中的方法

<!--配置注解驱动,相当于同时使用最新处理器映射跟处理器适配器,对json数据响应提供支持  -->
	<mvc:annotation-driven></mvc:annotation-driven>

ViewResolver:视图解析器

<!--配置视图解析器  -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>

SpringMVC是一个MVC的框架

springmvc与mybatis整合:

@Service
public class ItemServiceImpl implements ItemService {
	
	@Autowired
	private ItemMapper itemMapper;

	@Override
	public List<Item> getItemList() {
		return itemMapper.selectByExample(null);
	}

	@Override
	public Item getItemById(Integer id) {
		return itemMapper.selectByPrimaryKey(id);
	}

	@Override
	public void updateItem(Item item) {
		itemMapper.updateByPrimaryKeySelective(item);
	}

}
@Controller
public class ItemController {

	@Autowired
	private ItemService itemService;

	@RequestMapping("itemList")
	public ModelAndView itemList() {
		ModelAndView mav = new ModelAndView();

		List<Item> itemList = itemService.getItemList();

		mav.addObject("itemList", itemList);
		// mav.setViewName("/WEB-INF/jsp/itemList.jsp");
		mav.setViewName("itemList");
		return mav;
	}
    /**
	 * 跟据ID查询商品信息,跳转修改商品页面
	 * 演示默认支持的参数传递
	 * Model/ModelMap返回数据模型
	 * @param request
	 * @param response
	 * @param session
	 * @return
	 */
    /*@RequestMapping("itemEdit")
	public String itemEdit(Model model,ModelMap modelMap,HttpServletRequest request, HttpServletResponse response, HttpSession session) {
		String idStr = request.getParameter("id");
		System.out.println("response:" + response);
		System.out.println("session:" + session);
		// 查询商品信息
		Item item = itemService.getItemById(new Integer(idStr));
		//model返回数据模型
		model.addAttribute("item", item);
		//mav.addObject("item", item);
		return "itemEdit";
	}*/
}
//简单参数绑定,参数类型推荐使用包装数据类型,因为基础数据类型不可以为null 
@RequestMapping("itemEdit")
	public String itemEdit(Model model,@RequestParam(value="id",required=true,defaultValue="1") Integer ids) {
		// 查询商品信息
		Item item = itemService.getItemById(ids);
		//model返回数据模型
		model.addAttribute("item", item);
		//mav.addObject("item", item);
		return "itemEdit";
	}
/**
	 * 修改商品
	 * 演示pojo参数绑定
	 * @param item
	 * @return
	 */
	@RequestMapping("updateItem")
	public String updateItem(Item item,Model model){
		itemService.updateItem(item);
		model.addAttribute("item", item);
		model.addAttribute("msg", "修改商品信息成功");
		return "itemEdit";
	}

//传递pojo有一个关键点:只要表单里面的元素的name属性跟pojo的属性一一对应的上,就可以提交过来了
<!-- 解决post乱码问题 -->
	<filter>
		<filter-name>encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<!-- 设置编码参是UTF8 -->
		<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>
	
包装的pojo的属性:
通过(.)传递属性
<tr>
<td>商品名称:<input type="text" name="item.name"></td>
<td>商品价格:<input type="text" name="item.price"></td>
</tr>

@RequestMapping("queryItem")
	public String queryItem(QueryVo vo,Model model){
		if(vo.getItem() != null){
			System.out.println(vo.getItem());
		}
		
		//模拟搜索商品
		List<Item> itemList = itemService.getItemList();

		model.addAttribute("itemList", itemList);
		return "itemList";
	}

三层架构(持久层,service层,控制层)是构建代码的思维,mvc主要偏向控制器和web块, 

mvc是设计模式,三层架构是构建代码的方法

 

数据参数绑定:

List参数绑定:

${status.index} 输出行号,从0开始

${status.count} 输出行号,从1开始

@RequestMapping("queryItem")
	public String queryItem(QueryVo vo, Integer[] ids, Model model) {
		if (vo.getItem() != null) {
			System.out.println(vo.getItem());
		}
		if (ids != null && ids.length > 0) {
			for (Integer id : ids) {
				System.out.println(id);
			}
		}
		if (vo.getItems() != null && vo.getItems().size() > 0) {
			for (Item item : vo.getItems()) {
				System.out.println(item);
			}
		}

		// 模拟搜索商品
		List<Item> itemList = itemService.getItemList();

		model.addAttribute("itemList", itemList);
		return "itemList";
	}
<c:forEach items="${itemList }" var="item" varStatus="status">
<tr>
	<td><input type="checkbox" name="ids" value="${item.id}"></td>
	<%-- <td>${item.name }</td>
	<td>${item.price }</td>
	<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
	<td>${item.detail }</td>
	
	<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td> --%>
	
	<td>
	<input type="hidden" name="items[${ status.index }].id" value="${item.id}">
	<input type="text" name="items[${ status.index }].name" value="${item.name }"></td>
	<td><input type="text" name="items[${ status.index }].price" value="${item.price }"></td>
	<td>
	<%-- <fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/> --%>
	<input type="text" name="items[${ status.index }].createtime" value='<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>'>
	</td>
	<td><input type="text" name="items[${ status.index }].detail" value="${item.detail }"></td>
	<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>

</tr>
</c:forEach>
public class QueryVo {

	private Item item;
	
	private Integer[] ids;
	
	private List<Item> items;
	
	public List<Item> getItems() {
		return items;
	}

	public void setItems(List<Item> items) {
		this.items = items;
	}

	public Integer[] getIds() {
		return ids;
	}

	public void setIds(Integer[] ids) {
		this.ids = ids;
	}

自定义参数绑定:转换器:Converter

/**
 * 日期转换器
 * S:source 要转换的源类型
 * T:目标,要转换成的数据类型
 * @author Steven
 *
 */
public class DateConvert implements Converter<String, Date> {

	@Override
	public Date convert(String source) {
		Date result = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			result = sdf.parse(source);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return result;
	}

}

springmvc使用自定义转换器:

<!-- 配置注解驱动,相当于同时使用最新处理器映射跟处理器适配器,对json数据响应提供支持 -->
	<!-- 使用自定义转换器 -->
	<mvc:annotation-driven conversion-service="MyConvert" />
	
	<!-- 定义转换器 -->
	<bean id="MyConvert" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
		<property name="converters">
			<set>
				<bean class="com.itheima.springmvc.utils.DateConvert" />
			</set>
		</property>
	</bean>

方法返回值:

@RequestMapping("queryVoid")
	public void queryVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {

		// request响应用户请求
		// request.setAttribute("msg", "这个是request响应的消息");
		// request.getRequestDispatcher("/WEB-INF/jsp/msg.jsp").forward(request,
		// response);

		// 假设这里是跟据id查询商品信息,搜索不到商品
		if (true) {
			throw new MyException("你查找的商品不存在,请确认信息!");
		}

		int i = 1 / 0;

		// response响应用户请求
		// response.sendRedirect("itemList.action");

		// 设置响应的字符编码
		// response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");

		PrintWriter printWriter = response.getWriter();

		printWriter.println("这个是response打印的消息");
	}

乱码问题:

提交问题:
post乱码:过滤器解决
get乱码:tomcat配置  URIEncoding="utf-8"

响应乱码:
response乱码:获取getWriter之前,response.setCharacterEncoding("utf-8");

Springmvc中异常处理:

做一个全局异常处理器,处理所有没有处理过的运行时异常用于更友好地提示用户。

public class CustomerExceptionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object hanlder,
			Exception ex) {
		String result = "系统发生异常了,请联系管理员!";
		//自定义异常处理
		if(ex instanceof MyException){
			result = ((MyException)ex).getMsg();
		}
		ModelAndView mav = new ModelAndView();
		mav.addObject("msg", result);
		mav.setViewName("msg");
		return mav;
	}

}

springmvc.xml配置异常处理器:

<!-- 配置全局异常处理器 -->
	<bean class="com.itheima.springmvc.exception.CustomerExceptionResolver"/>

自定义异常类,修改异常处理器,加上异常判断:

public class MyException extends Exception {
	private String msg;
	

	public MyException() {
		super();
	}

	public MyException(String msg) {
		super();
		this.msg = msg;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}
}



@RequestMapping("queryVoid")
	public void queryVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {

		// request响应用户请求
		// request.setAttribute("msg", "这个是request响应的消息");
		// request.getRequestDispatcher("/WEB-INF/jsp/msg.jsp").forward(request,
		// response);

		// 假设这里是跟据id查询商品信息,搜索不到商品
		if (true) {
			throw new MyException("你查找的商品不存在,请确认信息!");
		}

		int i = 1 / 0;

		// response响应用户请求
		// response.sendRedirect("itemList.action");

		// 设置响应的字符编码
		// response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");

		PrintWriter printWriter = response.getWriter();

		printWriter.println("这个是response打印的消息");
	}

图片上传:配置虚拟目录,加入上传功能需要的jar包,配置多媒体处理器

<!-- 配置多媒体处理器 -->
	<!-- 注意:这里id必须填写:multipartResolver -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 最大上传文件大小 -->
		<property name="maxUploadSize" value="8388608" />
	</bean>
@RequestMapping(value = "updateItem", method = { RequestMethod.POST, RequestMethod.GET })
	public String updateItem(Item item, MultipartFile pictureFile, Model model) throws Exception {

		// 图片新名字
		String newName = UUID.randomUUID().toString();
		// 图片原来的名字
		String oldName = pictureFile.getOriginalFilename();
		// 后缀
		String sux = oldName.substring(oldName.lastIndexOf("."));
		// 新建本地文件流
		File file = new File("D:\\WebWork\\" + newName + sux);
		// 写入本地磁盘
		pictureFile.transferTo(file);

		// 保存图片到数据库
		item.setPic(newName + sux);

		itemService.updateItem(item);
		model.addAttribute("item", item);
		model.addAttribute("msg", "修改商品信息成功");
		return "itemEdit";
		// return "forward:itemList.action";
		// return "redirect:itemList.action";
	}
post请求:    <form id="itemForm"	action="${pageContext.request.contextPath }/updateItem.action" enctype="multipart/form-data" method="post">  

      
            <tr>
				<td>商品图片</td>
				<td>
					<c:if test="${item.pic !=null}">
						<img src="/pic/${item.pic}" width=100 height=100/>
						<br/>
					</c:if>
					<input type="file"  name="pictureFile"/> 
				</td>
			</tr>

json交互:

response可以响应json串

@RequestMapping("getItem")
	@ResponseBody
	public Item getItem(@RequestBody Item itemIn) {
		System.out.println(itemIn);
		// Item item = itemService.getItemById(1);
		itemIn.setName("手机");
		return itemIn;
	}

拦截器:

/**
 * 自定义拦截器
 * @author Steven
 *
 */
public class MyInterceptor implements HandlerInterceptor {

	//方法执行后被执行
	//处理异常,清资源,记录日志等等
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("MyInterceptor.afterCompletion.......");
	}

	//方法执行之后,返回ModelAndView之前被执行
	//设置页面的共用参数等等
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("MyInterceptor.postHandle.......");
	}

	//进入方法前被执行
	//登录拦截,权限验证等等
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("MyInterceptor.preHandle.......");
		//true放行,false拦截
		return true;
	}

}

拦截器案例应用,登录拦截器

<%@ 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>用户登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/user/login.action">
用户名:<input type="text" name="username" /><br>
密码:<input type="password" name="password" /><br>
<input type="submit">
</form>
</body>
</html>
1、有一个登录页面,需要写一个controller访问页面
2、登录页面有一提交表单的动作。需要在controller中处理。
a)	判断用户名密码是否正确
b)	如果正确 想session中写入用户信息
c)	返回登录成功,或者跳转到商品列表
3、拦截器。
a)	拦截用户请求,判断用户是否登录
b)	如果用户已经登录。放行
c)	如果用户未登录,跳转到登录页面。
/**
 * 用户请求处理器
 * @author Steven
 *
 */
@Controller
@RequestMapping("user")
public class UserController {

	@RequestMapping("toLogin")
	public String toLogin(){
		return "login";
	}
	
	@RequestMapping("login")
	public String login(String username,String password,HttpSession session){
		
		if(username.equals("admin")){
			session.setAttribute("username", username);
			return "redirect:/itemList.action";
		}
		
		return "login";
	}
}
/**
 * 登录拦截器
 * @author Steven
 *
 */
public class LoginInterceptor implements HandlerInterceptor {

	//方法执行后被执行
	//处理异常,清资源,记录日志等等
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
	}

	//方法执行之后,返回ModelAndView之前被执行
	//设置页面的共用参数等等
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
	}

	//进入方法前被执行
	//登录拦截,权限验证等等
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		//判断用户有没有登录
		Object object = request.getSession().getAttribute("username");
		if(object == null){
			response.sendRedirect(request.getContextPath() + "/user/toLogin.action");
		}
		//true放行,false拦截
		return true;
	}

}
<!-- 拦截器配置 -->
<mvc:interceptors>
		<mvc:interceptor>
			<!-- /**拦截所有请求,包括二级以上目录 -->
			<mvc:mapping path="/**"/>
			<bean class="com.itheima.springmvc.interceptor.MyInterceptor" />
		</mvc:interceptor>
		<mvc:interceptor>
			<!-- /**拦截所有请求,包括二级以上目录 -->
			<mvc:mapping path="/**"/>
			<bean class="com.itheima.springmvc.interceptor.MyInterceptor2" />
		</mvc:interceptor>
		<mvc:interceptor>
			<!-- /**拦截所有请求,包括二级以上目录 -->
			<mvc:mapping path="/**"/>
			<!-- 配置不拦截目录 -->
			<mvc:exclude-mapping path="/user/**"/>
			<bean class="com.itheima.springmvc.interceptor.LoginInterceptor" />
		</mvc:interceptor>
	</mvc:interceptors>

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值