Java网课基础笔记(23)19-08-05

 

1.上传图片

  • 配置虚拟目录

在tomcat上配置图片虚拟目录,双击tomcat

选中如下

点击左下角Modules

增加路径(Add  Externa Web Module)

在浏览器中输入指定路径即可查看图片http://localhost:8080/724739205.jpeg

  • 增加jar包

  • 配置上传解析器

在springmvc.xml中配置文件上传解析器

<!-- 文件上传解析器,id必须设置为multipartResolver -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!--  设置文件上传大小 -->
		<property name="maxUploadSize" value="5000000"></property>
	</bean>
  • editItem.jsp页面修改

设置表单可以进行文件上传

<!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
<!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> -->
<form id="itemForm"	action="${pageContext.request.contextPath}/updateitem.action" method="post" enctype="multipart/form-data" >
	

添加上传文件表格 

<tr>
				<td>商品图片</td>
				<td>
					<c:if test="${item.pic !=null}">
						<img src="/${item.pic}" width=100 height=100/>
						<br/>
					</c:if>
					<input type="file"  name="pictureFile"/> 
				</td>
			</tr> 
  • 在更新商品方法中添加图片上传逻辑
//更新商品
	@RequestMapping("/updateItem")
	public String updateItem(Item item,MultipartFile pictureFile) throws IllegalStateException, IOException{
		//图片上传
		//设置图片名称,不能重复,可以使用uuid
		String picName=UUID.randomUUID().toString();
		//获取文件名
		String oriName=pictureFile.getOriginalFilename();
		//获取图片后缀
		String extName=oriName.substring(oriName.lastIndexOf("."));
		//开始上传
		pictureFile.transferTo(new File("/Users/chenjiafeng/Pictures/"+picName+extName));
		//设置图片名到商品中
		item.setPic(picName+extName);
		//更新商品
		this.itemService.updateItem(item);
		return "forward:/itemEdit.action";
	}

效果

2.json数据交互

  • @RequestBody

作用:@RequestBody注解用于读取httpp请求到内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json数据)转换为Java对象并绑定到Controller方法的参数上

传统的请求参数:

itemEdit.action?id=1$name=zhangsan&age=12

现在的请求参数:使用post请求,在请求体里加入json数据

{

"id":1

"name":"测试商品"

"price":99.9

"detail":"测试商品描述"

"pic":"123456.jpg"

}

本例子应用:

@RequestBody注解实现接收http请求的json数据,将json数据 转换为Java对象进行绑定

  • @ResponsBody

作用:@ResponsBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Respons响应给客户端

本例子应用:@ResponsBody注解实现将Controller方法返回Java对象转换为json响应给客户端

  • 请求json,响应json实现

加入jar包

ItemController编写


//		测试json交互
		@RequestMapping("testJson")
		public @ResponseBody Item testJson(@RequestBody Item item) {
			System.out.println(item);
			return item;
		}

增加js

在editItem.jsp中添加测试方法

<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
  	$(function(){
	alert(1);
	var params = '{"id": 1,"name": "测试商品","price": 99.9,"detail": "测试商品描述","pic": "QQ20190315-1.jpg"}';
// 	$.post(url,params,function(data){
		//回调
// 	},"json");//
	$.ajax({
		url : "${pageContext.request.contextPath }/testJson.action",
		data : params,
		contentType : "application/json;charset=UTF-8",//发送数据的格式
		type : "post",
		dataType : "json",//回调
		success : function(data){
			alert(data.name);
		}
	});
	//alert(2); 
});
  

配置json转换器

如果不使用注解驱动<mvc:annotation-driven/>,就需要给处理器适配器配置json转换器,参考之前的学习自定义参数绑定

在spiringmvc.xml配置文件中,给处理器适配器加入json转换器

<!-- 处理器适配器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<property name="messageConverters">
			<list>
				<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
			</list>
		</property>
	</bean>

3.RESTFUL支持

Restful是一个资源定位及资源操作的风格。不是标准也不是协议,只是一个风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

资源:互联网所有的事物都可以被抽象为资源

资源操作:使用Post、Delete、Put、Get,使用不同方法对资源进行操作。分别对应 添加、删除、修改、查询。

传统方式操作资源 
http://127.0.0.1/item/queryItem.action?id=1     查询,GET 
http://127.0.0.1/item/saveItem.action                新增,POST 
http://127.0.0.1/item/updateItem.action            更新,POST 
http://127.0.0.1/item/deleteItem.action?id=1    删除,GET或POST

使用RESTFUL操作资源 
http://127.0.0.1/item/1            查询,GET 
http://127.0.0.1/item               新增,POST 
http://127.0.0.1/item               更新,PUT 
http://127.0.0.1/item/1            删除,DELETE

需求

RESTFUL方式实现商品信息查询,返回json数据

  • 从URL上获取参数

使用RESTful风格开发的接口,根据id查询商品,接口地址是: 
http://127.0.0.1/item/1 
我们需要从url上获取商品id,步骤如下: 

  1. 使用注解@RequestMapping(“item/{id}”)声明请求的url {xxx}叫做占位符,请求的URL可以是“item /1”或“item/2”
  2. 使用(@PathVariable() Integer id)获取url上的数据
//使用Restful风格开发接口,实现根据id查询商品
		@RequestMapping("item/{id}")
		public @ResponseBody Item queryItemById(@PathVariable() Integer id) {
			Item item=this.itemService.queryById(id);
			return item;
		}
		

如果@RequestMapping中表示为”item/{id}”,id和形参名称一致,@PathVariable不用指定名称。如果不一致,例如”item/{ItemId}”则需要指定名称@PathVariable(“itemId”)。

http://localhost:8080/SpringMVC-mybatis2/item.action?id=1

http://localhost:8080/SpringMVC-mybatis2/item/1.action


注意两个区别 

  1. @PathVariable是获取url上数据的。@RequestParam获取请求参数的(包括post表单提交)
  2. 如果加上@ResponseBody注解,就不会走视图解析器,不会返回页面,目前返回的json数据。如果不加,就走视图解析器,返回页面

4.拦截器

定义:Spring Web MVC的处理器拦截器类似于Servlet开发中的过滤Filter,用于对处理器进行预处理和后处理。

  • 拦截器定义

实现HandlerInterceptor接口,如下

public class Interceptor1 implements HandlerInterceptor {

	//controller执行后且视图返回后调用此方法
	//这里可得到执行controller时的异常信息
	//这里可记录操作日志
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor1-afterCompletion");
		
	}

	//controller执行后但未返回视图前调用此方法
	//这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor1-postHandle");
		
	}

	//Controller执行前调用此方法
	//返回true表示继续执行,返回false中止执行
	//这里可以加入登录校验、权限拦截等
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor1-preHandle");
		//返回true在能让controller方法执行,测试使用
		return true;
	}

}
public class Interceptor2 implements HandlerInterceptor {

	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor2-afterCompletion");
		
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor2-postHandle");
		
	}

	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Interceptor2-preHandle");
		//返回true在能让controller方法执行
		return true;
	}

}
  • 拦截器配置

在springmvc.xml中配置拦截器

<!-- 配置拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
		<!-- 所有的请求都进入拦截器 -->
			<mvc:mapping path="/**"/>
			<bean class="com.feng.ssm.terceptor.Interceptor1"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
			<bean class="com.feng.ssm.terceptor.Interceptor2"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

效果(注意拦截器方法的执行顺序)

preHandle- Controller执行前调用此方法- 按拦截器定义顺序执行

postHandle、afterCompletion-按拦截器定义逆序执行

afterCompletion只有preHandle返回true才调用

如果把拦截器Intercept1的preHandle返回flase(一旦中断,后面的拦截器不再执行)

@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		System.out.println("Interceptor1-preHandle");
		return false;
	}

拦截器应用

    处理流程

  • 有一个登录页面,需要写一个controller访问页面
  • 登录页面有一提交表单的动作。需要在controller中处理。
  1. 判断用户名密码是否正确
  2. 如果正确 想session中写入用户信息
  3. 返回登录成功,或者跳转到商品列表
  • 拦截器。
  1. 拦截用户请求,判断用户是否登录
  2. 如果用户已经登录。放行
  3. 如果用户未登录,跳转到登录页面

   编写登录login.jsp

<body>
<form action="${pageContext.request.contextPath }/user/login.action">
<label>用户名:</label>
<br>
<input type="text" name="username">
<br>
<label>密码:</label>
<br>
<input type="password" name="password">
<br>
<input type="submit">
</form>
</body>

用户登录Controller(UserController.java)

@Controller
@RequestMapping("user")
public class UserController {
	//跳转到登录页面
	@RequestMapping("tologin")
	public String tologin() {
		return "login";
	}
	//用户登录
	@RequestMapping("login")
	public String login(String username,String password,HttpSession session) {
		//校验用户登录
		System.out.println(username);
		System.out.println(password);
		//把用户名放到session中
		session.setAttribute("username", username);
		return "redirect:/item/itemList.action";
	}
}

编写拦截器(LoginIntercepor.java)


	//Controller执行前调用此方法
	//返回true表示继续执行,返回false中止执行
	//这里可以加入登录校验、权限拦截等
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		//从reques中获取session
		HttpSession session=request.getSession();
		//从session中获取username
		Object username=session.getAttribute("username");
		//判断username是否为null
		if(username!=null) {
			//如果不为空则放行
			return true;
		}else {
			//如果为空则跳转到登录页面
			response.sendRedirect(request.getContextPath()+"/user/tologin.action");
		}
		return false;
	}

配置拦截器

只能拦截商品到url,所有需要修改ItemController,让所有的请求都必须以item开头,如下图

@Controller
@RequestMapping("item")
public class ItemController {
	
}

在springmvc.xml配置拦截器

<!-- 配置拦截器 -->
	<mvc:interceptors>
		 <mvc:interceptor>
			<mvc:mapping path="/item/**" />
			<bean class="com.feng.ssm.controller.LoginInterceptor"></bean>
		</mvc:interceptor> 
	</mvc:interceptors>

测试:

输入http://localhost:8080/SpringMVC-mybatis2/user/tologin.action后,因为没有登录,所以自动跳转到登录页面

输入用户名密码后跳转

控制台显示

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值