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); }
相关推荐
结束数据方法的参数,该如何定义?-- 集合为自定义实体类中的结合属性,有几个实体类,改变下标就行了。<input id="add" type="button" value="新增visitor&quo