[java]46、SpringMVC-返回值
1、SpringMVC的返回值
1.1、无返回值情况
@Controller
public class VoidController {
@RequestMapping("/void")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("text/html; charset=UTF-8");
response.getWriter().write("MJ6666");
}
}
1.2、XML-方法返回
1、使用文本拼接方式
@Controller
public class XMLController {
@RequestMapping(value = "/xml1", produces = "application/xml; charset=UTF-8")
@ResponseBody
public String xml1() throws Exception {
return "<person name=\"小明\" age=\"28\" >"
+ "<car name=\"皮卡\" price=\"10000\" />"
+ "</person>";
}
}
2、使用第三方库
在pom.xml
配置如下
<!-- Model转XML字符串-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1</version>
</dependency>
Person.java
@XmlRootElement(name = "person")
public class Person {
private String name;
private Integer age;
private Car car;
@XmlElement
public String getName() {
return name;
}
...
}
Car.java
@XmlRootElement
public class Car {
private String name;
private Integer price;
@XmlElement
public String getName() {
return name;
}
}
XMLController.java
@Controller
public class XMLController {
@RequestMapping(value = "/xml2", produces = "application/xml; charset=UTF-8")
@ResponseBody
public Person xml2() throws Exception {
Person person = new Person();
person.setName("jack");
person.setAge(20);
Car car = new Car();
car.setName("BMW");
car.setPrice(1000000);
person.setCar(car);
return person;
}
}
1.3、JSON返回方式
1、在pom.xml
文件中配置
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
2、直接返回对象
@Controller
public class JSONController {
@RequestMapping(value = "/json2", produces = "application/json; charset=UTF-8")
@ResponseBody
public Student json2() {
Student student = new Student();
...
return student;
}
}
1.4、解决返回值乱码问题
1、在applicationContext.xml
中添加
<mvc:annotation-driven>
<mvc:message-converters>
<!--影响返回值是String的内容-->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8" />
</bean>
<!--影响返回值是Model对象(最后通过Jackson转成Json字符串)-->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="defaultCharset" value="UTF-8" />
</bean>
<!--影响返回值是Model对象(最后通过JAXB转成XML字符串)-->
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter">
<property name="defaultCharset" value="UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
1.5、JSP-ModelAndView
可以利用ModelAndView
将数据和视图绑定到一起,返回给客户端
@Controller
public class JSPController {
@RequestMapping("/jsp1")
public ModelAndView jsp1() {
ModelAndView mv = new ModelAndView();
mv.setViewName("/page/jsp1.jsp");
Dog dog = new Dog();
mv.addObject("dog", dog);
return mv;
}
}
在java代码中,路径问题总结:
1.假设请求路径:http://IP地址:端口/context_path/path1/path2/path3
2.假设转发路径:/page/test.jsp
1)、以斜线(/)开头,参考路径是context_path
2)、所以最终转发路径是:http://IP地址:端口/context_path + /page/test.jsp
3.假设转发路径是:"page/test.jsp"
1)、不以斜线(/)开头,参考路径是当前请求路径的上一层路径
2)、所以最终转发路径是:http://IP地址:端口/context_path/path1/path2/path3 + /page/test.jsp
在jsp、html代码中,路径问题总结:
1.假设请求路径:http://IP地址:端口/context_path/path1/path2/path3
2.假设转发路径:/page/test.jsp
1)、以斜线(/)开头,参考路径是http://IP地址:端口
2)、所以最终转发路径是:http://IP地址:端口 + /page/test.jsp
3.假设转发路径是:"page/test.jsp"
1)、不以斜线(/)开头,参考路径是context_path
2)、所以最终转发路径是:http://IP地址:端口/context_path + /page/test.jsp
1.6、JSP-String
不加上@ResponseBody
的String
返回值,也代码viewName
@RequestMapping("/jsp2")
public String jsp2(HttpServletRequest request) {
Dog dog = new Dog();
dog.setName("wanganw");
request.setAttribute("dog", dog);
return "/page/jsp2.jsp";
}
1.7、重定向在EL表达式中取参数
1、在viewName
前面加上redirect:
表示重定向
参考源码UrlBasedViewResolver
@RequestMapping("/jsp4")
public String jsp4() {
return "redirect:/page/jsp4.jsp?name=MingJia&age=19";
}
2、在JSP
中取出参数的值使用param
<dev>name:${param.name}, age:${param.age}</dev>
3、SpringMVC
默认会将ModelAndView
对象addObject
的内容,通过请求参数的形式传递给重定向的页面
在重定向的页面中可以通过request.getParameter
或${param}
获取
1.8、JSP-mvc:view-controller
可以使用<mvc:view-controller>
直接配置请求的路径和viewName
<mvc:view-controller path="/jsp5" view-name="/WEB-INF/page/jsp5.jsp" />
当没有使用@Controller
处理这个path
时,才会交给<mvc:view-controller>
去处理
使用了<mvc:view-controller>
后,建议加上<mvc:annotation-driven>
1.9、InternalResourceViewResolver
可以通过InternalResourceViewResolver
设置视图路径的公共前缀、后缀
在applicationContext.xml
中配置如下
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix" value="/WEB-INF/page2/"/>
<property name="suffix" value=".jsp"/>
</bean>
@Controller
@RequestMapping("/test")
public class JSPController2 {
@RequestMapping("/jsp1")
public String jsp1() {
return "jsp1";
}
}
受InternalResourceViewResolver
影响有
1、通过返回值ModelAndView
设置viewName
2、通过返回值String
设置的viewName
3、通过<mvc:view-controller>
设置的viewName
可以配置多个InternalResourceViewResolver
order
值越小,优先级越高
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="order" value="1" />
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="order" value="0" />
<property name="prefix" value="/WEB-INF/page2/"/>
<property name="suffix" value=".jsp"/>
</bean>
忽略InternalResourceViewResolver
有两种方法可以忽略InternalResourceViewResolver
的配置
方法①:在viewName
前面加上forward:
或redirect:
方法②:通过ModelAndView
的setView
方法
view.setView(new InternalResourceView("/person.jsp"))
mv.setView(new JstlView("person.jsp"));
// 重定向
mv.setView(new RedirectView("/person.jsp"));
实际上,之前通过返回值String
、ModelAndView
设置viewName
之后
SpringMVC
内部会根据具体情况创建对应的View
对象
InternamResourceView
、JstlView
、RedirectView
InternalResourceViewResolver
影响的是:没有带forward:
、redirect:
的viewName
1.10、自定义InternamResourceView
自定义InternamResourceView
可以实现,当一个InternalResourceViewResolver
拼接的路径找不到时,就尝试下一个order
较大的InternalResourceViewResolver
public class MyView extends InternalResourceView {
@Override
public boolean checkResource(Locale locale) throws Exception {
// 根据实际情况来返回
// 存在:返回true
// 不存在
String path = getServletContext().getRealPath("/") + getUrl();
File file = new File(path);
return file.exists();
}
}
在applicationContext.xml
中添加
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
...
<property name="viewClass" value="com.sj.view.MyView" />
</bean>
1.11、设置响应码
可以通过@ResponseStatus
设置响应码
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "客户端错误")