gpt4 book ai didi

spring-mvc - 如何为 URL 的数据库查找构建 spring mvc 自定义处理程序映射

转载 作者:行者123 更新时间:2023-12-05 02:21:46 24 4
gpt4 key购买 nike

在我的应用程序中,管理员用户可以控制项目的 URL,所以我想在数据库中查找注册的 URL,并重定向到相关的 Controller 方法。

我想弄清楚在某些情况下我应该返回什么:

  1. 缺少 URL - 我想抛出 404 错误。
  2. URL 已重定向 - 我想返回状态 301,重定向返回响应。
  3. URL 没问题 - 我想将 URL 重定向到相关的 Controller 。

值得注意的是, Controller 方法已经使用标准的请求映射,例如 /products/{productId},并且解析良好。

在代码中,它找到了 URL,我可以确定它是产品、页面等。但是我不确定如何重定向到 Controller 方法,或者 URL 是否被重定向或不存在如何分别返回错误码301或404...

有人能帮忙吗?

@Component
public class SeoUrlHandlerMapping extends AbstractUrlHandlerMapping {

private static Logger logger = LogManager.getLogger(SeoUrlHandlerMapping.class.getName());

@Autowired
private ProductSeoService productSeoService;
/**
* Looks up the handler for the url path.
* @param urlPath the URL path
* @param request the request.
* @return
* @throws Exception
*/
@Override
protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {

logger.entry("looking up handler for path: " + urlPath);

// this is just a test.
SeoUrl productUrl = productSeoService.findByURL(urlPath);
if (productUrl instanceof ProductSeoUrl)
{
ProductSeoUrl productSeoUrl = (ProductSeoUrl) productUrl;
logger.debug("Handling request to product " + productSeoUrl.getProduct());
request.setAttribute("id", productSeoUrl.getProduct().getId());
return getApplicationContext().getBeansOfType(ProductWebController.class);
}
return null;
}
}

最佳答案

好的,没有答案,但我会发布我最终得出的结论。我不确定这是否是最好的解决方案,但它似乎对我来说没问题。可能有更好的方法来设置模型映射或重写路径参数,但 servlet 请求工作正常...

所以这是主要的 MappingHandler:

/**
* The SeoUrlHandlerMapping will map between SEO URL requests and controller method
*/
@Component
public class SeoUrlHandlerMapping extends RequestMappingHandlerMapping {

private static Logger logger = LogManager.getLogger(SeoUrlHandlerMapping.class.getName());

@Autowired
private ProductSeoService productSeoService;

private final Map<String, HandlerMethod> handlerMethods = new LinkedHashMap<String, HandlerMethod>();


@Override
protected void initHandlerMethods() {

logger.debug("initialising the handler methods");
String[] beanNames =
getApplicationContext().getBeanNamesForType(Object.class);

for (String beanName : beanNames) {
Class clazz = getApplicationContext().getType(beanName);
final Class<?> userType = ClassUtils.getUserClass(clazz);

if (isHandler(clazz)){
for (Method method: clazz.getMethods())
{
SeoUrlMapper mapper = AnnotationUtils.getAnnotation(method, SeoUrlMapper.class);
if (mapper != null)
{
RequestMappingInfo mapping = getMappingForMethod(method, userType);
HandlerMethod handlerMethod = createHandlerMethod(beanName, method);
this.handlerMethods.put(mapper.seoType(), handlerMethod);
}
}
}
}
}

/**
* {@inheritDoc}
* Expects a handler to have a type-level @{@link org.springframework.stereotype.Controller} annotation.
*/
@Override
protected boolean isHandler(Class<?> beanType) {
return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) ||
(AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null));
}

/**
* The lookup handler method, maps the SEOMapper method to the request URL.
* <p>If no mapping is found, or if the URL is disabled, it will simply drop throug
* to the standard 404 handling.</p>
* @param urlPath the path to match.
* @param request the http servlet request.
* @return The HandlerMethod if one was found.
* @throws Exception
*/
@Override
protected HandlerMethod lookupHandlerMethod(String urlPath, HttpServletRequest request) throws Exception {

logger.entry("looking up handler for path: " + urlPath);

// this is just a test.
SeoUrl productUrl = productSeoService.findByURL(urlPath);
if (productUrl instanceof ProductSeoUrl) {
ProductSeoUrl productSeoUrl = (ProductSeoUrl) productUrl;

if (productSeoUrl.getStatus().equals(SeoUrlStatus.OK) || productSeoUrl.getStatus().equals(SeoUrlStatus.DRAFT))
{
request.setAttribute(SeoConstants.ID, productSeoUrl.getProduct().getId());
request.setAttribute(SeoConstants.URL_STATUS, productSeoUrl.getStatus().toString());
return this.handlerMethods.get("PRODUCT");
}else if (productSeoUrl.getStatus().equals(SeoUrlStatus.REDIRECTED))
{
request.setAttribute(SeoConstants.REDIRECT_URL, productSeoUrl.getRedirectURL());
return this.handlerMethods.get("REDIRECT");
}

// otherwise we let it return 404 by dropping through.
}

return null;
}
}

然后我在 Controller 方法上使用自定义注释来隔离处理程序方法:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SeoUrlMapper {
/**
* Assigns a type to this mapping.
* <p><b>This should match the SEOEntityType constants</b></p>.
*/
String seoType();
}

最后,在我的 Controller 方法中,我设置了注释来指示方法:

@SeoUrlMapper(seoType = "REDIRECT")
public RedirectView issueRedirect(ModelMap map, HttpServletRequest request)
{
logger.entry();
RedirectView view = new RedirectView();
view.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
view.setUrl((String)request.getAttribute("REDIRECT_URL"));
view.setExposeModelAttributes(false);
logger.exit();
return view;
}

@SeoUrlMapper(seoType = "PRODUCT")
public String viewProductInternal(ModelMap map, HttpServletRequest request)
{
Long id = (Long) request.getAttribute(SeoConstants.ID);
Product product = productService.findForDetailView(id);
return commonViewProduct(product, map);
}

关于spring-mvc - 如何为 URL 的数据库查找构建 spring mvc 自定义处理程序映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32087431/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com