简介:
本人是菜鸟,刚接触Java也没多长时间,就是希望能把自己学到的和大家分享而已,如有错误,还望大鸟给予指正。
距离上次写文章已经有几个月时间了,期间找工作,做项目的,虽然累点,但挺充实的。
就把在做项目时学到的一些东西和大家进行分享吧。
涉及到的内容:
Spring MVC 注解实现。
ajax json 返回格式。
Spring tiles 拼装页面。
需要的lib有:
名词解释:
json:
就不给大家上网copy了.就是一种格式.例如:
{
"employees": [
{ "firstName":"Bill" , "lastName":"Gates" },
{ "firstName":"George" , "lastName":"Bush" },
{ "firstName":"Thomas" , "lastName":"Carter" }
]
}
为什么用json:起始俺也就一知半解,单很显著的好处就是传输的数据量少了.
tiles:
其实就是拼装jsp.有什么好处呢?好处就是你可以独立的开发菜单部分,内容部分等等,使用时只需要拼装在一起就可以了
源代码:
1. 在web.xml中添加如下代码:
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-configuration.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 字符集 过滤器 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- session将在60分钟后过期 -->
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<!-- 定义当发生如下错误时,跳转的页面 -->
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/jsp/error/500.jsp</location>
</error-page>
2. 在spring-configuration中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xmlns:dwra="http://www.directwebremoting.org/schema/spring-dwr-annotations"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.directwebremoting.org/schema/spring-dwr
http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd
http://www.directwebremoting.org/schema/spring-dwr-annotations
http://www.directwebremoting.org/schema/spring-dwr-annotations.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- default-autowire含义为默认的装配行为,说白了就是匹配规则 -->
<!-- byName的含义是根据属性名自动装配,下面会在Controller层中介绍到 -->
<!-- 其还有byType属性,含义为通过类型自动装配,注意:如果有多个Type相同的Bean,则会抛出异常 -->
<!-- 还有constructor属性,与byType类似,区别是用于构造注入的参数 -->
<!-- 还有autodetect属性,根据Bean内部结构,决定用constructor还是byType -->
<!-- default-lazy-init含义为Bean是否延迟初始化 -->
<!-- 启用注解 -->
<mvc:annotation-driven>
<mvc:message-converters>
<!-- String转换器,解決 @ResponseBody 返回乱码问题.详细请参考: http://blog.csdn.net/nmgrlq/article/details/6285791 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- Json转换器,集成jackson -->
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<bean class="org.codehaus.jackson.map.ObjectMapper">
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 扫描包 -->
<context:component-scan base-package="com.spring.controller" />
<context:component-scan base-package="com.spring.service" />
<!-- 资源地址,不加这句的话,资源文件就会被Spring给拦截下来的(在web.xml中定义"/"全部都被拦截) -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- UrlMapping -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!-- JSP显示 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp"></property>
<property name="order" value="1"></property>
</bean>
<!-- Tiles显示 -->
<bean id="tilesviewResolver" class="org.springframework.web.servlet.view.tiles2.TilesViewResolver">
<!-- 这里的order是0,而jsp的order是1.表示优先去tiles定义文件(/WEB-INF/tiles-configueation.xml)查看是否有符合要求的,
如果没有,再去jsp查看是否有符合要求的页面 -->
<property name="order" value="0"></property>
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-configueation.xml</value>
<value>/WEB-INF/jsp/information/information-tiles.xml</value>
</list>
</property>
</bean>
</beans>
3. tiles-configueation.xml中
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<!-- 定义一个模板,sample_template.jsp中定义模板的布局 -->
<definition name="template_tiles" template="/WEB-INF/jsp/layout/sample_template.jsp">
<put-attribute name="part1-content" value="/WEB-INF/jsp/layout/part1.jsp" />
<put-attribute name="part2-content" value="/WEB-INF/jsp/layout/part2.jsp" />
</definition>
</tiles-definitions>
4. information-tiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<!-- 根据每个页面,定义不同的tiles,继承template_tiles模板 -->
<definition name="infomation/show" extends="template_tiles">
<!-- 在模板中的part3-content部分插入show.jsp -->
<put-attribute name="part3-content" value="/WEB-INF/jsp/information/show.jsp" />
<!-- 要传递的参数,显示页面标题 -->
<put-attribute name="jspTitle" value="信息显示" />
<put-attribute name="sampleParam" value="test" />
</definition>
</tiles-definitions>
5. sample_template.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- tiles:getAsString获得参数值 -->
<title><tiles:getAsString name="jspTitle"/></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="<%=request.getContextPath()%>/resources/js/jQuery/jQuery.js"></script>
<script src="<%=request.getContextPath()%>/resources/js/jQuery/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
alert($("#sampleParamDiv").text());
//可以通过这种方式将传递的值引入到js中进行计算
});
</script>
</head>
<body>
<!-- 这里定义jsp的大框架,包括布局等 -->
<div id="part1">
<!-- 将tiles-configuration.xml中 part1-content中定义的jsp插入到这里(也就是part1.jsp) -->
<tiles:insertAttribute name="part1-content" />
</div>
<div id="part2">
<tiles:insertAttribute name="part2-content" />
</div>
<div id="part3">
<tiles:insertAttribute name="part3-content" />
</div>
<div id="sampleParamDiv" style="display:none">
<tiles:getAsString name="sampleParam"/>
</div>
</body>
</html>
本人css太差了,要是有哪位朋友能帮我改进改进就好了,这样让别人看起来更直观一些.
6. index.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>主页</title>
</head>
<body>
Hello, Welcome to come here.
Now, click the button.
<form action="./login">
<input type="submit" value="跳到登录页面">
</form>
</body>
</html>
7. 404.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>
<body>
404! 你懂的
</body>
</html>
8. part1.jsp
<!-- 因为是将该部分插入到模板的jsp中,所以不用写 <head><body>等信息-->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
this is part1
9. login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登录页面</title>
</head>
<body>
<form action="<%=request.getContextPath()%>/login/checkLogin" method="post">
用户名: <input type="text" id="loginName" name="loginName" value="${UserEntity.loginName}"><br>
密 码 : <input type="password" id="pwd" name="pwd" >
<p>
<input type="submit" value="提交" >
<input type="reset" value="重置" >
</p>
<c:if test="${empty error}">请输入用户名密码</c:if><c:out value="${error}" />
</form>
</body>
</html>
10. UserEntity.java
package com.spring.entity;
public class UserEntity {
private String loginName;
private String pwd;
private String name;
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
11. LoginController.java
package com.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.spring.entity.UserEntity;
//@Controller 表明该Bean是个Controller层
//表示请求地址是login时,被该Controller捕获
@Controller
@RequestMapping(value = "/login")
public class LoginController {
@RequestMapping(method = RequestMethod.GET)
public String jumpPage() {
// JSP方式的显示,显示的jsp路径是 "/WEB-INF/jsp/login/login.jsp"(在spring-configuration中定义了)
return "login/login";
}
// 注意:这里的@RequestMapping的value值不能与@RequestMapping(value = "/login")中的value值一样
// 当url是/login/checkLogin时,执行该方法,并且是POST请求才可以
@RequestMapping(value = "/checkLogin", method = RequestMethod.POST)
public String login(@ModelAttribute("UserEntity") UserEntity user, Model model) {
// 在这里我们用了@ModelAttribute和Model.
// 用@ModelAttribute是将值放入session中,对应login.jsp中的value="${UserEntity.loginName}".
// 为什么这么写呢?首先看看如果不加"@ModelAttribute("UserEntity")"这段话会有什么结果.
// 结果就是如果输入错误,页面重新跳转到login.jsp.结果刚才用户填写的数据都没了(例如现在的密码是不是清空了),
// 如果这是个注册页面,用户辛辛苦苦填完信息,提交后一个错误导致所有数据清空,需要全部重新填写,用户会不会发疯呢
// 在这里用了Bean UserEntity来存放请求数据,只要变量名相同,Spring会自动帮我们将变量存到该Bean中
if (user.getLoginName().equals("mizhiwu") && user.getPwd().equals("mizhiwu")) {
// tiles的显示,会先去"/WEB-INF/tiles-configueation.xml"中查询(在spring-configuration中定义了)
return "infomation/show";
} else {
model.addAttribute("error", "用户名或密码不正确");
return "login/login";
}
}
}
12. show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
这是主菜单<br>
tiles集成后的结果相当于一个完整的jsp页面,请和template.jsp进行对比
<script type="text/javascript">
function check(){
//异步方式向服务器发送请求
$.ajax({
type: "GET",
url: "<%=request.getContextPath()%>/check/isPositiveNumber/" + $("#number").val(),
//data: "userId="+id+"&userPwd="+pwd,
dataType: "json", //这里表明返回数据是json
success: function(msg) {
//判断json中的success属性
if (msg.success) {
alert("输入的是正数");
} else {
alert("输入的是负数");
}
},
error :function(e){
alert("网络异常");
}
});
}
</script>
<form>
输入一个数<input type="text" id="number"><br>
<input type="button" οnclick="check()" value="确定">
</form>
13. ResultEntity.java
package com.spring.entity;
public class ResultEntity {
private boolean success;
private String message;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ResultEntity(boolean flag) {
success = flag;
}
}
14. CheckController.java
package com.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.spring.entity.ResultEntity;
import com.spring.service.CheckService;
@Controller
@RequestMapping(value = "/check")
public class CheckController {
// 这里就用到了之前定义的default-autowire="byName"
// spring自动装载了名字为CheckService的类给这个属性,就不需要我们来new CheckService对象了
@Autowired
CheckService checkService;
// 在spring-configuration.xml中因为已经集成了jackson,所以@ResponseBody返回的是一个json对象.
// 在这里用到了jackson将Bean转换成json的方法
@ResponseBody
@RequestMapping(value = "/isPositiveNumber/{number}")
public ResultEntity checkIsPositiveNumber(@PathVariable int number) {
// @PathVariable表示url中的值,在这里只是告诉大家也可以这么取值而已
return checkService.checkIsPositiveNumber(number) ? new ResultEntity(true) : new ResultEntity(false);
}
// @RequestParam表示请求时的参数,如果单个列举,而不用Bean获得(LoginController中login方法的UserEntity user Bean)
// 表示此参数不可缺少,如果想变成非必传参数,则加上required = false即可
public void test(@RequestParam String param1, @RequestParam(required = false) String param2,
@RequestParam(value = "id[]", required = false) String[] ids) {
}
}
15. CheckService.java
package com.spring.service;
import org.springframework.stereotype.Service;
@Service
public class CheckService {
public boolean checkIsPositiveNumber(int number) {
if (number >= 0) {
return true;
} else {
return false;
}
}
}
通过以上方法,我们避免了在spring.xml中定义臃肿的controller.而且代码也更简介了.
源代码下载: