restful基于SpringMVC的实现(下)

        闲话少叙,书开正题。
        我们就用例子,来看SpringMVC怎么实现的Restful。SpringMVC的具体细节我就先不讲了,有兴趣的可以看我的博客SpringMVC解析(还在写…...)

        SpringMVC是一个Controller层的框架,功能类似于Struts2。一个Controller框架,肯定有下面这三样。

        • 一个核心分发类 DispatcherServlet :负责接收请求,再转发给各个具体的处理类   
        • 具体的请求处理类  handler
        • 返回的结构页面(jsp等格式)

1.在web.xml中配置DispatcherServlet(SpringMVC的总控类,负责接收请求,并分发给相应的handler处理)

  
  
  	dispatcher
  	org.springframework.web.servlet.DispatcherServlet
  	1
  
  
  
  	
  	dispatcher 
  	/
  
2.实现handler类的编写(处理请求,指定返回的视图)

@Controller  //注解 EmpController 是一个 controller(handler)
@RequestMapping("/emp")  
public class EmpController {
	
	//@Resource(name="jdbcTemplate")
	@Autowired
	@Qualifier(value="jdbcTemplate")
	private JdbcTemplate jdbcTemplate;
	
	/**
	 * 获取员工信息
	 * */
	@RequestMapping(method=RequestMethod.GET)
	//model:springmvc在调用方法前,会创建一个隐含的模型对象,用于存储数据,供view和controller交互数据
	//相当于struts2的值栈
	public String list(Model model){
		List list = jdbcTemplate.query("select * from emp", new RowMapper(){
			public EmpVO mapRow(ResultSet rs, int index) throws SQLException {
				EmpVO emp = new EmpVO();
				emp.setEmpno(rs.getInt("empno"));
				emp.setEname(rs.getString("ename"));
				emp.setJob(rs.getString("job"));
				emp.setSal(rs.getDouble("sal"));
				return emp;
			}
		});
		model.addAttribute("empList", list);
		return "empList";
	}
	
	/**
	 * 员工信息编辑页面
	 * */
	//{emp}通配符,配合@PathVariable传参
	@RequestMapping(value="/{empno}/edit",method=RequestMethod.GET)
	public String edit(@PathVariable Integer empno,Model model){
		String selSql =  "select * from emp where empno = " + empno ;
		EmpVO vo = jdbcTemplate.queryForObject(selSql, new RowMapper(){
			public EmpVO mapRow(ResultSet rs, int arg1) throws SQLException {
				EmpVO emp = new EmpVO();
				emp.setEmpno(rs.getInt("empno"));
				emp.setEname(rs.getString("ename"));
				emp.setJob(rs.getString("job"));
				emp.setSal(rs.getDouble("sal"));
				return emp;
			}
		});
		model.addAttribute("emp", vo);
		return "empEdit";
	}
	
	/**
	 * 更新员工信息
	 * */
	@RequestMapping(value="/{empno}",method=RequestMethod.PUT)
	public String update(@PathVariable Integer empno,@RequestParam String xiao, EmpVO vo, Model model){
		String updateSql = "update emp set ename=?,job=?,sal=? where empno = ? ";
		jdbcTemplate.update(updateSql, new Object[]{vo.getEname(),vo.getJob(),vo.getSal(),vo.getEmpno()});
		return "redirect:/emp/";
	}
}

采用的注解实现,为了简单,直接在controller中调用了JDBC,各位见谅哈。

3.实现返回的视图jsp

一个index.jsp,一个empList.jsp,一个empEdit.jsp。见名思议,具体不写了。

4.配置dispatcher-servlet.xml的配置


	
	
	
    
    
    
    
    
    	
    	
     
    
    
    
    			
    			
    			
    			
    
    
	
	
		
	

基本的实现就是上面那样。下面我们进一步的看几个问题。

1.按照上面的配置,你请求emp的列表资源(ProjectName/emp/  +get),和emp的编辑页面((ProjectName/emp/{empno}/edit+ get)不会有问题。但是请求保存更新(ProjectName/emp/{empno}/edit +put)的时候,会失败。原因是一些浏览器不支持put/delete等表单提交方式。解决方案呢,SpringMVC已经替我们想好了。

在html的form表单中,添加一个hidden,指定提交的方法。注意form的method一定要是post,而不是put等

然后在web.xml中添加filter

  
  
  	HiddenHttpMethodFilter
  	org.springframework.web.filter.HiddenHttpMethodFilter
  
  
  
  	HiddenHttpMethodFilter
  	dispatcher
  
这样HiddenHttpMethodFilter就会把http的请求方式,封装成我们指定的方式。

         2.为了让url实现restful风格,我们的url请求没有用.do或.html的方式。同时我们又用“/”拦截了所有请求。这就会导致一个问题,对静态资源的请求找不到文件了。not found 404.

但是放心,魔高一尺,道高一丈,这种小问题,Spring一定会提供解决方案的。

	
	
So easy.这样,Spring就不会拦截resources的资源了。 或者可以用下面的方式,使用servlet原生API。这个要配置在DispatcherServlet的前面,保证他先执行。(可以不同的服务中中间件,对这个默认的servlet名字不一致,所以不确定哪个中间件前,还是不要这么用了)


    default
    *.jpg


    default
    *.js


    default
    *.css
 

3.当我调用完put方法后,需要调用list查询所用EMP信息,并返回。但是当我写return  "forward:/emp"时,却找不到list方法。原因,此时http的请求方式还是put,而我的list 对应的method是get。最后,我使用了 return "redirect:/emp/"; 重定向请求。成功了,但是我认为这不是最佳方案,后来我想可以把http的请求方式,先改为get,再forward。不知是否可行。不知其他大神是怎么解决这个问题的。

注:request.getMethod();  获取请求的提交方式; get,post,put,delete...

但是貌似不支持request.setMethod();

以上是关于springmvc实现restful的一些总结。有不对的地方,望大家积极指正。

你可能感兴趣的:(东来西扯--交流会)