我们的第一个例子是用的真是路径,那如果我们用逻辑路径怎么配置呢,很简单,只需要在spring的配置文件中配置视图解析器时配置前缀和后缀即可:
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
看一下我们的Action类的写法:
/**
* 控制器
* @author user
*
*/
public class UserAction implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
System.out.println("增加用户");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "增加用户成功");
modelAndView.setViewName("success");
return modelAndView;
}
}
modelAndView.setViewName(“success”);这里我们写的就是一个逻辑名称:
下面我们来写一下,在springmvc中如何防止乱码。
我们通常的做法是写一个过滤器。来防止乱码:
在spring中提供了一个专门针对post乱码问题的类,我们只需要在web,xm中进行配置即可:
<!-- 配置一个spring提供的针对post的中文乱码问题 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果我们想通过后台来切换页面,比如在项目中,我们访问不到在WEB-INF下的页面,那么我们通过后台怎么访问呢?
比如我们写一个超链接
<a href = "${basePath}index.action"></a>
当我们点击的时候想访问Web-INF下的Index.jsp。我们在配置文件中配置:
<!-- 配置Action(无) -->
<!-- 映射器 (无)-->
<!-- 适配器 -->
<!-- 视图解析器 (无)-->
<!-- 专用于jsp到jsp的转发控制器 -->
<bean class="org.springframework.web.servlet.mvc.ParameterizableViewController" name="/index.action">
<!-- 转发的视图名 -->
<property name="viewName" value="/WEB-INF/index.jsp"></property>
</bean>
这样我们就可以通过后台来访问页面。
通常我们接收的数据,都是一个JavaBean,接收的时候,我们需要接收到消息,在new 一个JavaBean,再赋值,那么spring能不能类似于Mybatis在查询的时候,能够自动生成javaBean呢?答案是可以的。
首先我们创建一个javaBean包括三个属性:
/**
* 员工
* @author user
*
*/
public class Emp {
private String username;
private String gender;
private Date hiredate;
public Emp() {
// TODO Auto-generated constructor stub
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
}
这里我们会连同spring中如何处理时间一起说明一下:
创建我们的Action类:
/**
* 单例
* 处理类
* @author user
*springmvc不能讲String类型转成Date类型,必须自定义类型转换器
*/
public class EmpAction extends AbstractCommandController{
public EmpAction() {
//自动将表单参数封装到Emp对象中去
this.setCommandClass(Emp.class);
}
/**
* 自定义的类型转换器,讲String转换成Date类型(格式yyyy-MM-dd)
*/
@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
//向springmvc内部注入一个自定义的转换器
//参数一:最终将String转成什么类型的字节码
//参数二:属性编辑器:自定义的转换规则
// CustomDateEditor参数一:时间的格式,参数二:可不可以为空
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
/*
* obj 表示封装后的实体
* error表示封装时产生的异常
*/
@Override
protected ModelAndView handle(HttpServletRequest req, HttpServletResponse resp, Object obj, BindException error)
throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "增加员工成功");
Emp emp = (Emp) obj;
//将emp封装到ModelAndView中
modelAndView.addObject("emp", emp);
System.out.println(emp.getUsername()+" "+emp.getGender()+" "+emp.getHiredate().toLocaleString());
modelAndView.setViewName("/jsp/success.jsp");
return modelAndView;
}
}
需要注意的几点:
1.这里我们是继承类:AbstractCommandController,重写里面的handle方法。
2.handle方法的参数有四个,前两个就是request和response,第三个就是产生的实体。第四个是产生实体过程中可能出现的异常。
3.写构造方法,
public EmpAction() {
//自动将表单参数封装到Emp对象中去
this.setCommandClass(Emp.class);
}
这一步就是自动将表单里面的参数封装到Emp对象中去。
在这里需要注意一下,我们创建的实体的属性(username,gender,hiredate)和我们添加用户的页面的input框的name属性要一致。在下面中会仔细说明。
3.Spring mvc不能将String类型转成Date类型,我们必须自定义类型转换器。
重写initBinder,利用该方法的第二个参数ServletRequestDataBinder binder向springmvc内部注入一个自定义的转换器。binder.registerCustomEditor的第一个参数是最终将String转成什么类型的字节码,参数二:属性编辑器:自定义的转换规则。CustomDateEditor参数一:时间的格式,参数二:可不可以为空。
我们看一下jsp页面:
添加用户页面:
<%@ 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>Insert title here</title>
</head>
<%
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
pageContext.setAttribute("basePath", basePath);
%>
<body>
<a href="${ basePath}index.action" style="text-decoration: none">首页</a>
<hr>
<form action="${basePath }add.action" method="post">
<table align="center">
<tr>
<th>姓名</th>
<td><input type="text" name = "username"></td>
</tr>
<tr>
<th>性别</th>
<td>
<input type="radio" name = "gender" value="男" checked="checked">男
<input type="radio" name = "gender" value="女">女
</td>
</tr>
<tr>
<th>入职时间</th>
<td><input type="text" name = "hiredate" value = "2018-09-20"></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
</body>
</html>
获取页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!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>Insert title here</title>
</head>
<%
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
pageContext.setAttribute("basePath", basePath);
%>
<body>
成功<br>
${requestScope.message}<br>
姓名:${requestScope.emp.username }<br>
性别:${requestScope.emp.gender }<br>
入职时间:${requestScope.emp.hiredate}<br>
入职时间: <fmt:formatDate value="${requestScope.emp.hiredate}" type="date" dateStyle="full"/>
<!--
1)fmt:formatDate 来源于 http://java.sun.com/jsp/jstl/fmt
2)fmt:formatDate作用是格式化日期的显示,例如:2015年5月10日 星期日
3)value表示需要格式化的值
4)type表示显示日期,时间,都显示
type=date表示只显示日期
type=time表示只显示时间
type=both表示日期时间均显示
5)dateStyle表示显示日期的格式:short/medium/default/long/full
-->
</body>
</html>