试试把xml和javascript写到同一个文件里面

本文探讨了解决服务器在返回错误信息时,根据不同客户端请求(XML或JSON)的兼容性问题。通过巧妙利用注释符特性,实现了一种同时符合XML与JavaScript语法的错误反馈方案。

服务器现在同时输出json和xml两种数据,取决于服务程序和页面之间的约定。在程序遇到问题的时候会返回错误信息,也按照相同的约定会返回json或者xml格式的数据。比如当页面请求xml的时候服务会返回:

<?xmlversion="1.0"encoding="gb2312"?><error>出错了</error>

而当页面请求的是json的时候服务器会返回

alert("出错了")

但是今天遇到的问题是,服务器本身出了问题,打个比方,比如说遇到404或者500错误,无从得知现在应该返回xml还是json格式的出错信息。于是服务器就统一返回了一个xml格式的错误。但是页面这个时候是用script标签在请求一个json数据,接收到一个xml文件,直接就产生语法错误了。改成json的话,请求xml的地方也无法提供正确的错误提示。

这个时候我们需要的就是服务器返回一个同时符合javascript和xml语法的错误信息,或者说把xml和javascript的错误信息放到一起。

嗷嗷研究过把css和javascript放在一个文件里面,主要是为了可以较少一个http请求。把xml和javascript放在一起有一些不同。

最容易想到的是“<!-- ”注释符。由于历史原因,这个xml里面的注释符在javascrip里面是一个单行注释符,也就是说在javascript里面,它以回车符为结束,而在xml里面是以-->结束。因此如果用这样一个符号开始一个文件,我们就可以通过控制它的结束位置来控制它在不同语法下面的意义。

error.xml

<!----><error>出错了</error><!--
alert("出错了")//
-->

注意,从xml的角度上来看,这个xml没有带<?xml部分,因此不能制定encoding编码,只能用默认的utf-8编码输出。或者用实体替换和转义符来回避编码问题

error.xml

<!----><error>&#x51fa;&#x9519;&#x4e86;</error><!--
alert("\u51fa\u9519\u4e86")//
-->

之所以刻意不带<?xml,是因为按照规范<?xml必需出现在最开始部分,虽然IE可以允许<?xml前面出现<!-- -->注释,但是FF就没有这样的灵活性了。

简单的在IE下面用两种语法处理这个文件的一个例子:

<HTML>
<HEAD>
<TITLE>test</TITLE>
<METANAME="Author"CONTENT="emu">
</HEAD>
<BODY>
<xmlsrc="error.xml"id="err"></xml>
<SCRIPTLANGUAGE="JavaScript"src="error.xml"charset="utf-8"></SCRIPT>
<SCRIPTLANGUAGE="JavaScript">
alert(err.getElementsByTagName(
"error")[0].xml)
</SCRIPT>
</BODY>
</HTML>
这是一个非常典型且关键的问题! > **“第一步我就访问不了 `http://localhost:8080/your-app/dwr/`”** 这意味着 DWR 的前端接口没有暴露出来,可能是配置、部署或安全限制的问题。 --- ## ✅ 简短回答: 你访问不到 `/dwr/` 页面,通常是因为以下原因之一: 1. ❌ DWR 没有正确配置(`dwr.xml` 缺失或错误) 2. ❌ Web.xml 中未注册 DWR Servlet 3. ❌ 项目未正确部署或服务未启动 4. ❌ 被防火墙、Nginx 或 Spring Security 拦截 5. ❌ URL 路径写错了(比如上下文路径不对) 下面我们一步步排查并解决。 --- ## 🛠 第一步:确认你的应用是否真的启用了 DWR ### ✅ 1. 检查 `web.xml` 是否注册了 DWR Servlet 打开你的项目中的: ``` src/main/webapp/WEB-INF/web.xml ``` 查找是否有如下配置: ```xml <servlet> <servlet-name>dwr</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> <!-- 必须设为 true 才能访问 /dwr/ 页面 --> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> ``` 📌 关键点: - 必须有这个 `<servlet>` `<servlet-mapping>` - `debug` 参数必须是 **`true`**,否则 `/dwr/` 主页会被禁用(出于安全考虑) 🔧 **修复方法**: 如果你发现没有这段代码,请手动添加进去,并重新部署项目。 --- ### ✅ 2. 检查 `dwr.xml` 是否存在且正确 路径应该是: ``` src/main/webapp/WEB-INF/dwr.xml ``` 内容示例: ```xml <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd"> <dwr> <allow> <!-- 示例:暴露一个 Spring Bean --> <create creator="spring" javascript="DwrInvokeDataAction"> <param name="beanName" value="dwrInvokeDataAction"/> </create> <!-- 允许转换 DTO 对象 --> <convert converter="bean" match="com.yourcompany.dto.GgClauseTextDto"/> </allow> <!-- 可选:加入全局日志 --> <init-param> <param-name>org.directwebremoting.log.level</param-name> <param-value>DEBUG</param-value> </init-param> </dwr> ``` 📌 如果 `dwr.xml` 文件缺失或路径错误,DWR 就不会加载任何类,自然也无法访问。 🔧 **建议**: - 确保文件名是 `dwr.xml` - 放在 `WEB-INF/` 目录下 - XML 格式要合法(不要拼错标签) --- ### ✅ 3. 确认服务器已启动且项目成功部署 #### 操作步骤: 1. 启动你的应用服务器(Tomcat / Jetty / WebLogic 等) 2. 查看控制台输出日志,搜索关键词: - `DwrServlet` - `Loading DWR configuration from [/WEB-INF/dwr.xml]` - `Started DWR Servlet` ✅ 正常日志示例: ``` INFO [main] DwrServlet.init() Initializing DWR servlet INFO [main] Configurator.loadConfiguration() Loading DWR configuration from [/WEB-INF/dwr.xml] INFO [main] AbstractConfigurator.addCreate() Added create: javascript=DwrInvokeDataAction ``` ❌ 如果没看到这些日志 → DWR 没有加载! --- ### ✅ 4. 检查实际访问的 URL 是否正确 #### 常见错误: | 错误写法 | 正确写法 | 说明 | |--------|---------|------| | `http://localhost:8080/dwr/` | `http://localhost:8080/your-app/dwr/` | 缺少上下文路径(Context Path) | | `http://localhost:8080/app/dwr` | `http://localhost:8080/app/dwr/` | 少了末尾斜杠 `/` | | `http://127.0.0.1:8080/myapp/DWR/` | `http://127.0.0.1:8080/myapp/dwr/` | 大小写敏感!应为小写 `dwr` | 🔍 如何查上下文路径? - 如果你是 Maven 项目,默认可能是:`/your-project-name` - 在 `pom.xml` 中看 `<finalName>myapp</finalName>` - 或者在 IDE(如 IntelliJ/Eclipse)中查看 Deployment Assembly - 访问首页试试:`http://localhost:8080/your-app/index.jsp` 🎯 所以完整正确的 URL 是: ``` http://localhost:8080/your-app/dwr/ ``` --- ### ✅ 5. 是否被 Spring Security / Shiro / 防火墙拦截? 很多系统为了安全,默认禁止访问 `/dwr/` 接口。 #### 检查点: 1. 打开浏览器 F12 → Network → 刷新页面 2. 看请求 `/dwr/` 返回的是: - `404 Not Found` → 路径不存在 or 未部署 - `403 Forbidden` → 权限不足(被安全框架拦截) - `401 Unauthorized` → 需要登录 - `Connection Refused` → 服务没起来 or 端口错 #### 解决方案(开发环境临时放开): ##### 如果用了 Spring Security,在 `SecurityConfig.java` 中放行: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/dwr/**").permitAll() // 允许访问 DWR .antMatchers("/assets/**").permitAll() .anyRequest().authenticated(); } } ``` ⚠️ 注意:生产环境不建议开放 `/dwr/` 页面,只保留接口调用即可。 --- ### ✅ 6. 检查 JAR 包是否齐全 DWR 需要以下核心 JAR(放在 `WEB-INF/lib/`): - `dwr.jar` (核心包) - `commons-logging.jar` - (可选)`spring-context.jar` 等依赖 📦 如果你是 Maven 项目,请检查 `pom.xml` 是否包含: ```xml <dependency> <groupId>org.directwebremoting</groupId> <artifactId>dwr</artifactId> <version>3.0.2-RELEASE</version> </dependency> ``` 👉 没有这个 jar,DwrServlet 根本找不到,自然无法响应请求。 --- ## 🔍 排查流程图(一步一步来) ```mermaid graph td A[打不开 /dwr/] --> B{检查 web.xml} B -- 无 DwrServlet --> C[添加 Servlet 配置] B -- 有 --> D{debug=true?} D -- 否 --> E[改为 true] D -- 是 --> F{dwr.xml 存在?} F -- 否 --> G[创建 dwr.xml] F -- 是 --> H{项目部署成功?} H -- 否 --> I[重新打包部署] H -- 是 --> J{URL 路径正确?} J -- 否 --> K[修正 context path] J -- 是 --> L{F12 抓包看状态码} L -- 404 --> M[检查 WAR 包结构] L -- 403/401 --> N[检查权限拦截器] L -- 200 --> O[成功!] ``` --- ## 💡 实用调试命令 & 方法 ### 1. 查看 WAR 包结构(确认文件是否存在) ```bash jar -tf target/your-app.war | grep dwr ``` 你应该能看到: ``` WEB-INF/web.xml WEB-INF/dwr.xml WEB-INF/lib/dwr-3.0.2-RELEASE.jar dwr/ dwr/index.html dwr/engine.js dwr/interface/ ``` 如果没有 → 说明打包失败或配置缺失。 --- ### 2. 手动测试 DWR JS 是否可访问 尝试直接访问: ``` http://localhost:8080/your-app/dwr/engine.js ``` ✅ 应该返回 JavaScript 内容,而不是 404。 如果连这个都打不开 → 说明 DWR 完全没生效。 --- ### 3. 在 Java 代码中打印一句话验证类是否加载 在 `DwrInvokeDataAction` 类的静态块中加一句: ```java static { System.out.println(">>>>> DwrInvokeDataAction 已被加载!"); } ``` 重启后看控制台有没有这句输出。 --- ## ✅ 成功后的样子 当你一切配置正确后: ✅ 访问: ``` http://localhost:8080/your-app/dwr/ ``` 你会看到网页显示: ``` Direct Web Remoting (DWR) v3.0.2-RELEASE This web container has the DWR Servlet installed. It allows JavaScript in a web browser to call methods on Java classes running on this server. The following classes are supported: • DwrInvokeDataAction - dispatch(String method, Map params) - testMethod() Click on a class name for more information and online testing. ``` 🎉 恭喜!你现在可以继续下一步了! --- ## ✅ 总结:为什么你打不开 `/dwr/` | 原因 | 检查方式 | 解决办法 | |------|----------|-----------| | `web.xml` 没配 DwrServlet | 查看文件 | 添加 servlet 配置 | | `debug=false` | 查 init-param | 改为 `true` | | `dwr.xml` 缺失 | 查路径 | 创建并填写正确内容 | | 上下文路径错误 | 浏览器地址栏 | 补全 `/your-app/` | | 被安全框架拦截 | F12 看状态码 | 开发环境临时放行 | | 缺少 dwr.jar | `jar -tf xxx.war` | 加入依赖 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值