【发布时间】:2017-07-03 22:12:06
【问题描述】:
我在用什么?
- Tomcat 7.0.56
- JAVA 1.8
- Spring MVC
- jQuery
目标是什么?
我正在实现一个内容目录。
例如,用户搜索特定的姓名或电话号码。然后在页面左侧显示联系人列表。在右侧应该显示被选中的联系人的详细信息。
问题出在哪里?
我的问题在于显示细节。
我的代码:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html >
<%@ include file="includes/header.jsp" %>
<body>
<div class="pageContainer container-fluid">
<div class="row">
<%@ include file="searchBar.jsp" %>
</div>
<div class="row">
<div class="containerOverView col-lg-5 col-md-6 col-sm-12 col-xs-12">
<%@ include file="overView.jsp" %>
</div>
<div class="containerDetailView col-lg-7 col-md-6 col-sm-12 col-xs-12">
<%@ include file="detailView.jsp" %>
</div>
</div>
</div>
</body>
</html>
detailView.jsp
<ul class="flex-container">
<li class="flex-item-photo">Photo</li>
<li class="flex-item-pdetails">Personal Details</li>
<li class="flex-item-cdetails">Company Details</li>
<li class="flex-item-map">Map:
${detailSearchResult.name}
</li>
</ul>
MainController.java
// Delivers the refresh-information for the ajax request, when the detail view gets reloaded
@RequestMapping(value = "/refreshDetail", method = RequestMethod.POST)
@ResponseBody
private String refreshDetailView(HttpServletRequest hsr, @RequestParam String id, ModelMap model){
model.addAttribute("detailSearchResult", Dao.getDetailViewData(id));
return "detailView";
}
main.js
$(document).ready(function(){
$(".overViewListEmployee").click(function () {
var id = $(this).find(".overViewEmployeeID").text();
console.log("Works: " + id + ".");
$.ajax({
type: "POST",
accepts: "text/plain",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "/refreshDetail",
data: ({"id" : id}),
success: function(response) {
$(".containerDetailView").html(response);
}
});
});
});
究竟是什么不起作用?
在我看来,ajax 请求并没有真正得到有效的响应。据我了解,ajax 接受各种响应,但不知何故,当我调试 JavaScript 时,它说响应有 Response Error: response is not defined
错误代码:
使用上面的代码:
400:加载资源失败:服务器响应状态为 400(错误请求)
当我在 main.js 中注释掉以下行时:
//contentType: "application/json; charset=utf-8",
406:(不可接受)
什么有效? (由于调试)
当我调试代码时,我看到 id 的值正确地进入了控制器,并且函数 Dao.getDetailView(id) 也正常工作。所以这实际上只是响应的问题。
我还尝试了什么?
我不确定它是否可以这样工作,方法是返回一个带有 detailView.jsp 页面名称的字符串,因为我不知道 model 是否应该重新加载该页面 我添加的属性也随之而来,并在 index.jsp 中呈现(其中包含 detailView.jsp)。
所以我也试着把 Controller-Function 像这样:
// Delivers the refresh-information for the ajax request, when the detail view gets reloaded
@RequestMapping(value = "/refreshDetail", method = RequestMethod.POST)
private ModelAndView refreshDetailView(@RequestParam String id, ModelMap model){
model.addAttribute("detailSearchResult", Dao.getDetailViewData(id));
return new ModelAndView("detailView");
}
并从 main.js 中删除这一行:
accepts: "text/plain",
我也尝试过返回模型:
return new ModelAndView("detailView", model);
我不经常使用 JavaScript,所以这可能是一个非常愚蠢和明显的错误,但我似乎找不到它。我真的尝试了我能找到的所有东西,但看起来我被困在这里了。
对于这个案例,我非常感谢任何形式的帮助 :)
更新:
main.js
$(".overViewListEmployee").click(function () {
var id = parseInt($(this).find(".overViewEmployeeID").text());
console.log("Works: " + id + ".");
$.ajax({
type: "POST",
accept:"text/html",
//contentType: "application/json; charset=utf-8",
dataType: "html",
url: "/refreshDetail",
data: ({"id": id}),
success: function(response) {
$(".containerDetailView").html(response);
}
});
});
MainController.java
// Delivers the refresh-information for the ajax request, when the detail view gets reloaded
@RequestMapping(value = "/refreshDetail", method = RequestMethod.POST, produces = MediaType.TEXT_HTML_VALUE)
@ResponseBody
private ModelAndView refreshDetailView(HttpServletRequest hsr, @RequestBody IdObject id, ModelMap model){
model.addAttribute("detailSearchResult", Dao.getDetailViewData(id.getId()));
return new ModelAndView("detailView", model);
}
IdObject.java
public class IdObject {
int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
现在根本没有到达控制器 - 仍然出现 415 错误。
更新 2:
WebInit.java(之前)
@Configuration
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer{
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
WebInit.java(之后)
@Configuration
public class WebInit implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(WebConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(RootConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
现在我不确定这是否是您的意思,但从我读到的@AnnotationDrivenConfig 与AnnotationConfigWebApplicationContext 相同。而且由于我是使用纯 Java 的配置来做的,所以我想这就是我要走的路。
但我仍然遇到同样的错误。
WebConfig.java
@Configuration
@EnableWebMvc
@ComponentScan("com.avectris.newtel")
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/view/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/sass_compiled/**").addResourceLocations("/sass_compiled/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
converter.setObjectMapper(objectMapper);
converters.add(converter);
super.extendMessageConverters(converters);
}
}
【问题讨论】:
-
在您返回 html 代码时,您的 ajax 请求中的数据类型属性应该是“html”。并返回一个 ModelAndView。如果你返回一个字符串,你需要删除@ResponseBody。
-
@alfcope - 感谢您的快速回复!我试过了。不幸的是,我仍然收到 400: Bad Request 错误。知道还有什么可能导致这种情况吗?
-
将接受更改为 'accepts:{html: "text/html"}' 并将 "produces = MediaType.TEXT_HTML_VALUE" 包含到控制器的请求映射注释中。
-
@alfcope - 仍然得到同样的错误。当我调试 JS 时,它仍然抛出 Reference Error: response is not defined。
-
另外,您正在使用 RequesParam 在控制器上获取 id。当您发送 json 对象时,您需要使用 RequestBody 并使用具有 id 属性的对象。如果将 url 更改为“/refreshDetail?id="+id 之类的内容,则无需在控制器上进行任何更改,但需要从 ajax 对象中删除内容类型和数据。
标签: javascript ajax spring jsp model