SpringMVC是一个Controller层的框架,功能类似于Struts2。一个Controller框架,肯定有下面这三样。
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的一些总结。有不对的地方,望大家积极指正。