SpringMVC常见的应用(文件上传设置、json交互、restful风格编码小代码)

SpringMVC常见应用

        1@RequestMapping

                此注解放在类上用于窄化请求、防止重名

@Controller
@RequestMapping("item")
public class ItemsController {
	
	@Autowired
	private ItemsService itemsService;
	
	@RequestMapping(value="/list",method=RequestMethod.POST)
	public ModelAndView itemsList() {
		List<Items> items  = itemsService.getItems();
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("itemlist", items);
		modelAndView.setViewName("itemList");
		return modelAndView;
	}

        2、Controller返回值

            a、ModelAndView(对request的封装和扩展)

            两个重要的方法:addObject(obj,obj)-指定返回页面的数据,也是使用的request.setAttribute()方法。setViewName()指定返回的页面。

            b、String(推荐使用)

            返回普通的字符串-就是页面去掉扩展名的名称,数据通过model填写。

            返回的字符串以forward:开头表示请求转发

            返回的字符串以redirect:开头表示重定向

            c、返回void(破坏了SpringMVC的结构不建议使用)

            使用setAttribute设置返回页面的数据,使用sendRedirect和getRequestDispatcher("页面的路径").forward(req,rep)方式指定返回页面。

            在这种方式下,Controller不走SpringMVC组件,那么需要指定页面完整的路径/WEB-INF/jsp/**

            相对路径:相对于当前目录,也就是当前类的目录下,这个时候可以使用相对路径跳转

            绝对路径:从项目名开始

            在SpringMvc中不论forward和redirect,都是以"/"开头的为绝对路径,不以"/"开头的是相对路径。forward:/items/list.action为绝对路径,redirect:list.action是相对路径。

            3、上传文件

                 a、配置虚拟目录

                    在tomcat安装目录下conf/server.xml中添加:

<Context docBase="/home/lxj/temp" path="/pic" reloadable="false"/>

                    访问http://localhost:8080/pic/xx.jpg,即可访问/home/lxj/temp下的图片。

在eclipse下创建:

        如果设置成功,那么可以在浏览器中访问文件:

            b、修改form表单属性,添加enctype="multipart/form-data"

<form id="itemForm"	action="${pageContext.request.contextPath }/updateitem.action" enctype="multipart/form-data" method="post">
	其中enctype="multipart/form-data"在上传文件的时候必须加上
            c、配置文件上传组件
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设置上传文件的最大尺寸为5MB -->
		<property name="maxUploadSize">
			<value>5242880</value>
		</property>
	</bean>
            
Controller:
		public String updateItem(MultipartFile pictureFile, Items items)  {
try {
	//		1、获取文件名
			String fileStr = pictureFile.getOriginalFilename();
	//		2、生成新的文件名,防止重名
			String newFileName = UUID.randomUUID().toString()+fileStr.substring(fileStr.lastIndexOf("."));
			pictureFile.transferTo(new File("/home/lxj/temp/"+newFileName));
			items.setPic(newFileName);
			itemsService.updateItems(items);
			return "success";
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
	return "error";
}
	}

            扩展:如果是多个文件上传,那么将input的name属性变为一致,将Controller中的MultipartFile变为数组接收,亦可以直接使用common-fileupload组件直接接收form表单数据,他会将每个Input变为一个域,然后迭代判断是否为文件,进行操作。

            4、json数据交互

                @ResponseBody注解读取http的内容(字符串),通过SpringMVC提供的HttpMessageConverter接口,将读到的内容转化成json、xml等格式的数据并绑定Controller方法的参数上。

                @RequestBody  SpringMVC自动的将json转换成Java中的pojo,前提是json中的key必须和pojo的属性名一致。

测试:导入Jquery
	<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>
	<script type="text/javascript">
	function sendJson(){
		$.ajax({
			type:"post",
			url:"${pageContext.request.contextPath }/sendJson.action",
			contentType:"application/json;charset=utf-8",
			data:'{"name":"测试商品","price":99.9}',
			success:function(data){
				alert(data);
			}
		});
	}
	</script>
	<input type="button" value="json" οnclick="sendJson()"/>
Controller:
	//@RequestBody SpringMVC自动的将json转换成Java中pojo,
//	json中的key必须和pojo的属性名一致
//	@ResponseBody自动的将pojo转换成json格式
	@RequestMapping("sendJson")
	@ResponseBody
	public Items sendJson(@RequestBody Items  items) {
		System.out.println(items);
		return items;
	}

        5、restful风格

                通俗的将知识一种规范和人为约定的资源定位和资源操作风格,要求url中只能有名词,不能有动词。

        修改servlet-mapping的映射路径

<!-- *.action 拦截后缀名action结尾的
		 /拦截所有,不包括jsp
		 /*拦截所有包括jsp
	-->
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
        修改url
<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
	变为:
	<td><a href="${pageContext.request.contextPath }/items/itemEdit/${item.id}/${item.name}">修改</a></td>
	
Controller:接收参数已经映射的写法
	/**
	 * springmvc中默认支持的类型,可以加也可以不加
	 * @param req
	 * @param rep
	 * @param model
	 * @param session
	 * @PathVariable获取url中传过来的参数,域页面/itemEdit/{id}/{name}和方法中的形参名必须和url的一致
	 * @return
	 */
	@RequestMapping("/itemEdit/{id}/{name}")
	public String itemEdit(@PathVariable("id") Integer id,@PathVariable("name") String name ,HttpServletRequest req,HttpServletResponse rep,Model model) {
			Items items=itemsService.findItemsById(id);
//			Model其实就是使用request传递参数,只是对request进行了扩展
			model.addAttribute("item", items);
//			如果返回的是一个简单的字符串,SpringMvc就会认为这是一个页面
		return "editItem";
	}

        如果是使用了redirect重定向的情况下:

/	接受pojo类型、要求页面个的属性名称必须和接受参数的pojo类型参数属性名一致
	@RequestMapping("/updateitem")
//	public String updateItem(Integer id ,String name ,Float price,String detail) {
	public String updateItem(MultipartFile pictureFile, Items items,Model model)  {
try {
	//		1、获取文件名
			String fileStr = pictureFile.getOriginalFilename();
	//		2、生成新的文件名,防止重名
			String newFileName = UUID.randomUUID().toString()+fileStr.substring(fileStr.lastIndexOf("."));
			pictureFile.transferTo(new File("/home/lxj/temp/"+newFileName));
			items.setPic(newFileName);
			itemsService.updateItems(items);
			model.addAttribute("id", items.getId());
//			redirect:重定向,forward:请求转发
			return "redirect:itemEdit";
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
	return "error";
}
浏览器:
	出现404错误,并且http://localhost:8080/day19-ssm/items/itemEdit?id=1,仍然是以问号传参数的
	改变:
	//	接受pojo类型、要求页面个的属性名称必须和接受参数的pojo类型参数属性名一致
	@RequestMapping("/updateitem")
//	public String updateItem(Integer id ,String name ,Float price,String detail) {
	public String updateItem(HttpServletRequest request,HttpServletResponse response,MultipartFile pictureFile, Items items,Model model)  {
try {
	//		1、获取文件名
			String fileStr = pictureFile.getOriginalFilename();
	//		2、生成新的文件名,防止重名
			String newFileName = UUID.randomUUID().toString()+fileStr.substring(fileStr.lastIndexOf("."));
			pictureFile.transferTo(new File("/home/lxj/temp/"+newFileName));
			items.setPic(newFileName);
			itemsService.updateItems(items);
//			model.addAttribute("id", items.getId());
//			redirect:重定向,forward:请求转发
//			String name = new String(items.getName().getBytes("iso8859-1"), "utf-8");
			String starName = items.getName();
			response.setHeader("Content-type", "text/html;charset=UTF-8"); 
			String name = 
					java.net.URLEncoder.encode(starName,"UTF-8");
			return "redirect:itemEdit"+"/"+items.getId()+"/"+name;
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
	return "error";
}

        注意:之所以要进行URL编码,是因为在浏览器中中文乱码了,设置响应头告诉浏览器解析方式没有,tomcat中get解析编码集设置没用,所以只能是想到进行查看响应消息中的restful风格下的编码,发现中文给编码了,所以想到这里也需要人为的进行编码。

        6、SpringMVC拦截器

            a、创建拦截器:实现org.springframework.web.servlet.HandlerInterceptor

public class interceptor1 implements HandlerInterceptor {

//	Controller已经执行,ModelAndView已经返回,
//	记录操作日志、记录IP等
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("========="+"interceptor1"+"afterCompletion=====");
	}

// Controller已经执行,ModelAndView没有返回
//	处理全局需要的信息
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("========="+"interceptor1"+"postHandle=====");

	}

//	返回布尔值,返回true放行、返回false拦截(最常用的)
//	执行时机:Controller还未执行,ModelAndView还未被返回
//	通常用于用户登录检查、权限验证
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("========="+"interceptor1"+"preHandle=====");
		return false;
	}

}

        SpringMVC中配置拦截器:

<!-- 拦截器配置 
		多个拦截器,按照配置的顺序进行执行
		-->
	<mvc:interceptors>
		<mvc:interceptor>
		<!-- 要拦截所有必须配置为/** -->
			<mvc:mapping path="/**"/>
			<bean class="cn.lier.interceptor.interceptor1"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
		<!-- 要拦截所有必须配置为/** -->
			<mvc:mapping path="/**"/>
			<bean class="cn.lier.interceptor.interceptor2"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

        实例:登录验证

                    1、编写一个Controller、一个跳转登录页、一个登录校验方法

                    2、登录页面

                    3、编写拦截器

创建login.jsp:
	<form action="${pageContext.request.contextPath }/login/submit" method="post">
		<table>
			<tr>
				<td>用户名:<input type="text" name="name" /></td>
			</tr>
			<tr>
				<td>密 码:<input type="password" name="pwd"/></td>
			</tr>
			<tr>
				<td><input type="submit" name="登录"/></td>
			</tr>
		</table>
	</form>
	LoginController:
	@Controller
@RequestMapping("/login")
public class LoginController {
	
	@RequestMapping("/login")
	public String login() {
		
		return "login";
	}
	
	@RequestMapping("/submit")
	public String submit(String name ,String pwd,HttpServletRequest request) {
		HttpSession session = request.getSession();
//		从数据库中获取数据,匹配
		if(name != null) {
			session.setAttribute("name", name);
		}
		return "redirect:/items/list";
	}
}
	LoginInterceptor:
		@Override
	public boolean preHandle(HttpServletRequest req, HttpServletResponse arg1, Object arg2) throws Exception {
//		1、判断是否为登录路径,是放行
		if(req.getRequestURI().lastIndexOf("/login")>0) {
			return true;
		}
//		判断session中是否有登录信息,如果没有跳转到登录页面
		if(req.getSession().getAttribute("name") !=null) {
			return true;
		}
		System.out.println("========");
		req.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(req, arg1);
		return false;
	}
           SpringMVC拦截器配置:
	<!-- 拦截器配置 
		多个拦截器,按照配置的顺序进行执行
		-->
	<mvc:interceptors>
		<mvc:interceptor>
		<!-- 要拦截所有必须配置为/** -->
			<mvc:mapping path="/**"/>
			<bean class="cn.lier.interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

        效果图:

                输入http://localhost:8080/day19-ssm/items/list转发到了login.jsp

                            

 输入密码提交跳转首页这里是列表页:





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值