ajax获取Struts框架中的json编码异常和Struts中的主控制器异常的解决办法

一:ajax获取自定义Struts框架中的json编码  出现以下 问题:    

1,强制flush输出  json编码打印在首页

2, 不强制flush js会解析json 打印出来的是错误的jsp页面   却没有跳转到错误页面

3,  ajax中的dataType的json 改为text 会打印错误的页面数据  

问题关键代码如下;

//处理登陆的servlet	
		// 获得登陆页面提交的数据
		String username = request.getParameter("username");
		String userpwd = request.getParameter("userpwd");

		try {
			// 连接数据库查询用户是否存在
			Connection conn = DBUilt.getConn();
			String sql = "select userid from role_user where userid=? and userpwd=?";
			PreparedStatement pstm = conn.prepareStatement(sql);
			pstm.setString(1, username);
			pstm.setString(2, userpwd);
			ResultSet rs = pstm.executeQuery();
			if (rs.next()) {
				String name = rs.getString(1);
				// 存在就存到会话对象中
				HttpSession session = request.getSession();
				session.setAttribute("name", name);

    PrintWriter out = response.getWriter();

		String username = (String) request.getSession().getAttribute("name");
		try {
			// 连接数据库查询用的权限
			// 使用JSon编码格式获取,java转为json
			String str = "{}";
			// 队列存储json的编码格式
			ArrayList<JSONObject> jsonlist = new ArrayList<JSONObject>();
			Connection conn2 = DBUilt.getConn();
			String limitSql = "select parentnode, menuname,menuhref ,maxnode from role_menu where menuid  in (select menuid from role_role where userid=?)";
			PreparedStatement pstm2 = conn2.prepareStatement(limitSql);
			pstm2.setString(1, username);
			ResultSet rst = pstm2.executeQuery();
			while (rst.next()) {
				JSONObject jsonobj = JSONObject.fromObject(str);
				jsonobj.put("node", rst.getString(1));
				jsonobj.put("menu", rst.getString(2));
				jsonobj.put("href", rst.getString(3));
				jsonobj.put("max", rst.getString(4));
				jsonlist.add(jsonobj);// 将转化的JSON对象放到队列中
			}
			rst.close();
			out.write(jsonlist.toString());// 写到页面
			out.flush();
			// json打印在首页 json的接受解析不会执行,
			// 不强制flush js会解析json 打印出来的是错误的jsp页面 页面页面却没有跳转
			System.out.println(jsonlist.toString());
				
				return "index.jsp";
			} else {
				return "loginFail.html";
			}
		} catch (Exception e) {
			return "loginFail.html";
		}

jsp页面的代码:

<script type="text/javascript">
var date;
   //创建ajax函数页面加载是自动的处理
	$(function() {
		alert("AJAX执行了");
		$.ajax({
			type : "POST",
			async : true, //异步提交数据
			url : "MenuAction.ser",//请求的路径
			dataType : "json", //数据的格式
			error:function(){
				alert("json没有获取到!!!!");
			},
			success : function(data) {//请求成功的数据
				for(var nn=0; nn<data.length;nn++){
	               var node=data[nn].node;
	               var menu=data[nn].menu;
	               var href=data[nn].href;
	               var max=data[nn].max;
	               d.add(node, max, menu, href);  
	               alert(node+"<>"+max+"<>"+ menu+"<>"+ href);
			   }	
				  
			}
		});
	});
	
	
</script>
</head>

<body>
	<div class="dtree">
	
	
	</div>
</body>

解决思路:

1,问题一的解决: ajax是异步提交数据,需要将ajax获取后台数据的json的Action写成一个新的类

2,问题二.三的解决: 在后台的json数据返回中response需要设置响应的数据格式,设置响应response.setContentType("text/json");

修改后的代码:

 1,   连接数据库的代码和返回json数据的代码分开写两个类 并t且在json格式类中设置("text/json")格式    代码如下;

 数据库的连接类;

//处理登陆的servlet
public class LoginServlet implements ActionInterface {
	@Override
	public String exectu(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		
		// 获得登陆页面提交的数据
		String username = request.getParameter("username");
		String userpwd = request.getParameter("userpwd");

		try {
			// 连接数据库查询用户是否存在
			Connection conn = DBUilt.getConn();
			String sql = "select userid from role_user where userid=? and userpwd=?";
			PreparedStatement pstm = conn.prepareStatement(sql);
			pstm.setString(1, username);
			pstm.setString(2, userpwd);
			ResultSet rs = pstm.executeQuery();
			if (rs.next()) {
				String name = rs.getString(1);
				// 存在就存到会话对象中
				HttpSession session = request.getSession();
				session.setAttribute("name", name);

				
				return "index.jsp";
			} else {
				return "loginFail.html";
			}
		} catch (Exception e) {
			return "loginFail.html";
		}	
	}
}

//ajax动态获取json的Action类

public class MenuAction implements ActionInterface {

	@Override
	public String exectu(HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		response.setContentType("text/json");
		PrintWriter out = response.getWriter();

		String username = (String) request.getSession().getAttribute("name");
		try {
			// 连接数据库查询用的权限
			// 使用JSon编码格式获取,java转为json
			String str = "{}";
			// 队列存储json的编码格式
			ArrayList<JSONObject> jsonlist = new ArrayList<JSONObject>();
			Connection conn2 = DBUilt.getConn();
			String limitSql = "select parentnode, menuname,menuhref ,maxnode from role_menu where menuid  in (select menuid from role_role where userid=?)";
			PreparedStatement pstm2 = conn2.prepareStatement(limitSql);
			pstm2.setString(1, username);
			ResultSet rst = pstm2.executeQuery();
			while (rst.next()) {
				JSONObject jsonobj = JSONObject.fromObject(str);
				jsonobj.put("node", rst.getString(1));
				jsonobj.put("menu", rst.getString(2));
				jsonobj.put("href", rst.getString(3));
				jsonobj.put("max", rst.getString(4));
				jsonlist.add(jsonobj);// 将转化的JSON对象放到队列中
			}
			rst.close();
			out.write(jsonlist.toString());// 写到页面
			out.flush();
			// json打印在首页 json的接受解析不会执行,
			// 不强制flush js会解析json 打印出来的是错误的jsp页面 页面页面却没有跳转
			System.out.println(jsonlist.toString());
		} catch (Exception ef) {
			ef.printStackTrace();
		}
		return null;
	}
}

js中的ajax代码;不用修改

     

二:自定义的struts框架 主控制器出现转发错误及解决思路;

  Struts的主控制中转发的错误代码:

try{
//str是servlet返回的是一个地址
	if (str != null) {
         //转发到相应的地址
		request.getRequestDispatcher(str).forward(request, response);
		}else{
       //为null就转发到错误的页面
		request.getRequestDispatcher(str).forward(request, response);
			}
		} catch (Exception e) {
    //出现异常就转发到错误的页面
		request.getRequestDispatcher("loginFail.html").forward(request,
				response);
		}

 
 程序运行会出现以下异常:

//在MVC设计模式中,主控制器不要进行else的判断,否者会以下错误

//java.lang.IllegalStateException: Cannot forward after response has been committed

  responsed不可以被重复的提交

思路分析;

   如果地址不null空 程序会转发到响应的str地址页面,地址为null就会先执行else的转发再执行try-catch()中的转发,这样会导致response响应两次,就会出现上面的response被重复的提交 ,解决办法除掉else的响应

修改后的代码:

try{
	//str是servlet返回的是一个地
if (str != null) {
	request.getRequestDispatcher(str).forward(request, response);
	    }
	} catch (Exception e) {
       request.getRequestDispatcher("loginFail.html").forward(request,response);
   }

 

  

相关推荐